LINUX.ORG.RU

[C] работа со строками

 


0

0

портируя код под windows заметил косяк в функции wchar_t tmp[7]; swprintf (&tmp[0], 6, L"%s", "eng");

в линуксе все ок, а в винде мало того, что это дистриктед, так ещё и не работает нормально... при чем

swprintf (&tmp[0], 6, L"%d", 2);

работает нормально


может винда считает, что 6 - это sizeof(tmp) и делит его еще пополам?

xydo ★★
()
Ответ на: комментарий от alex_custov

>swprintf(tmp, 6, L"%s", L"eng");

тогда нада %ls. вообщем проблема решилась, необходимо было написать %S вместо %s... ппц какой-то

st0ke
() автор топика
Ответ на: комментарий от Reset

А разве в C есть UTF-8? Покажите код вывода UTF-8 строки с пробелами между букв на стандартном С. Просто интересно.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>А разве в C есть UTF-8? Покажите код вывода UTF-8 строки

а что utf-8 строка, это не последовательность байт?
а то, как байты преобразуются в картинки на терминале, пусть терминал и занимается

dimon555 ★★★★★
()
Ответ на: комментарий от Reset

>> За wchar_t руки бы отрывал. utf-8 для кого придумали?

Внутри программы ИМХО wchar_t - идеальный вариант. А для передачи по сети или записи в файл - UTF-8.

Deleted
()
Ответ на: комментарий от undet

>> puts ("UTF-8 string"); ?

А кто сказал что у пользователя на терминале именно UTF-8,а не KOI8-R или например CP1251?

Deleted
()
Ответ на: комментарий от Deleted

>> puts ("UTF-8 string"); ?

>А кто сказал что у пользователя на терминале именно UTF-8,а не KOI8-R или например CP1251?

Тех у кого в терминале KOI-8 или тем паче CP1251 в расчет можно и не брать.

Absurd ★★★
()
Ответ на: комментарий от dimon555

> а что utf-8 строка, это не последовательность байт?
> а то, как байты преобразуются в картинки на терминале, пусть терминал и занимается


Ключевое слово - с пробелами между символов. Символ это не байт - надо уметь итерироваться по UTF-8 символам. В стандартном С я не знаю функций - значит надо использовать дополнительные библиотеки либо штудировать стандарт Unicode. Оба варианта сложнее использования стандартных возможностей языка С.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>Ключевое слово - с пробелами между символов.

ключевое слово - коды Хаффмена, диву даёшься, как оно так... вроде разное число бит на символ, а распознаёт всегда однозначно

dimon555 ★★★★★
()
Ответ на: комментарий от itanko

код Хаффмена самый известный пример просто

dimon555 ★★★★★
()
Ответ на: комментарий от Absurd

А iconv для кого придумали? Оно вообще-то на всех системах есть. Внутри программы всё в utf-8 и в человеческом char *, а iconv'ом потом печатай хоть в iso-8859-5.

Reset ★★★★★
()
Ответ на: комментарий от Legioner

Стандартный Си идет лесом. glib есть везде (даже под visual studio) и нет ничего понятнее чем вот такая конструкция:

for (char * p = s; *p; p = g_utf8_next_char(p)) { ... }

Надо знать только и это и про существование семейства функций wprintf и им подобных можно забыть как страшный сон.

Тут мы имеем дело с обычным char *. Без всяких накладных расходов на хранение латиницы (что бывает в 90% случаев). В utf-8 заведомо влазят все unicode символы. Не нужно использовать всякие компиляторо-зависимые вещи типа перечисленных выше. Связь со скриптовыми языками типа python'а становится тривиальной и не надо делать дополнительных преобразований из wchar_t * в char *, чтоб отправить в python.

wchar_t устарел лет 10 назад.

Reset ★★★★★
()
Ответ на: комментарий от Reset

>> А iconv для кого придумали? Оно вообще-то на всех системах есть. Внутри программы всё в utf-8 и в человеческом char *, а iconv'ом потом печатай хоть в iso-8859-5.

А зачем такой изврат когда есть wchar_t?

Deleted
()
Ответ на: комментарий от Reset

>> Тут мы имеем дело с обычным char *. Без всяких накладных расходов на хранение латиницы (что бывает в 90% случаев). В utf-8 заведомо влазят все unicode символы.

Без всяких накладных расходов говорите? Ну-ну =). Попробуйте в UTF-8 строке заменить в середине 10 символов.

>> Не нужно использовать всякие компиляторо-зависимые вещи типа перечисленных выше.

Какие компиляторо-зависимые вещи?

>> Связь со скриптовыми языками типа python'а становится тривиальной и не надо делать дополнительных преобразований из wchar_t * в char *, чтоб отправить в python.

Разве что это реальный минус, так что тут я согласен.

>> wchar_t устарел лет 10 назад.

Вот под такими заявлениями неплохо бы давать пруфлинк. В альтернативной ОС например начиная с NT (вроде) внутри WinAPI везде "широкие" строки.

Deleted
()
Ответ на: комментарий от Reset

Так-то оно так, однако в винде (если уж пошел разговор про визуальную студию) таки тащить лишнюю зависимость ради одной смешной функции g_utf8_next_char - моветон, имхец.

Да и при портировании на какое-нибудь хитрый ембеддед, для которого нету глиба с винтом, тоже не очень. Никого агитировать не буду, каждый пускай решит сам, однако скажу, что для себя я выбрал, что лучше уж хоть и велосипед, но свой - маленький и контролируемый. Да и если взглянуть исторически, то в плане utf8 велосипедом по отношению к rune.c является таки glib.

itanko
()
Ответ на: комментарий от Deleted

Между прочим, Java и C# тоже используют широкие строки... Из си-пи-пишного можно вспомнить Qt. Там тоже 16 бит на символ. Видимо, Reset просто не использует KDE :) Тогда как в Gtk действительно применяется UTF8, и это было причиной некоторой "тормузнотости" последней в обработке строк, за что гномерам приходилось несколько раз оправдываться в прошлом.

UTF8 хорош как интерфейс ввода-вывода и как средство совместимости со старым или другим софтом. При прочих равных хранение данных внутри программы в виде магической последовательности UTF8 - немного странная идея, когда память обычно менее важный фактор, чем женерал перформанс.

dave ★★★★★
()
Ответ на: комментарий от dave

>> UTF8 хорош как интерфейс ввода-вывода и как средство совместимости со старым или другим софтом. При прочих равных хранение данных внутри программы в виде магической последовательности UTF8 - немного странная идея, когда память обычно менее важный фактор, чем женерал перформанс.

+INF

Deleted
()
Ответ на: комментарий от dave

QString это отдельная тема, оно хранит в utf-16 и совместимо с char*.

А чего происходит с wchar_t если символ не влазит в 65535? Опять же возникает вопрос как в середине строки что-то менять.

По поводу компиляторозависимых вещей, вот уже для нормальной работы такого:

wchar_t str[]=L"Привет мир!!!";

надо думать о ключиках компилятора, чтобы оно сконвертило строку из нужной кодировки в wchar_t.

Если нужна скорость и совместимость, то надо использовать QString или UString (из icu), но никак не wchar_t.

Reset ★★★★★
()
Ответ на: комментарий от Reset

>А чего происходит с wchar_t если символ не влазит в 65535?

вантузятник, это тока у вас там длина wchar_t равна 16 битам, в линуксе 32 бита...

st0ke
() автор топика
Ответ на: комментарий от Reset

>> QString это отдельная тема, оно хранит в utf-16 и совместимо с char*.

Вы ошиблись, UTF-16 никак не может быть совместимо с char * (UTF-8).

>> А чего происходит с wchar_t если символ не влазит в 65535? Опять же возникает вопрос как в середине строки что-то менять.

WinAPI AFAIK в принципе не поддерживаются символы, не влезающие в 2 байта. В линуксе sizeof(wchar_t) == 4, в других юникс-подобных ОС подозреваю что так же. То есть длинна строки всегда равна количеству элементов wchar_t в ней.

>> По поводу компиляторозависимых вещей, вот уже для нормальной работы такого: wchar_t str[]=L"Привет мир!!!";

За такое надо убивать не зависимо от того, wchar_t там или char. В коде - ASCII-only. Локализованные строки хранить в отдельных файлах в UTF-8 (чтобы не возникало проблем например с порядком байт) и при загрузке конвертировать в wchar_t-строки (конвертирование символа - это просто несколько сдвигов и сложений).

>> Если нужна скорость и совместимость, то надо использовать QString или UString (из icu), но никак не wchar_t.

Ну собсно... я выше уже всё объяснил.

Deleted
()
Ответ на: комментарий от Reset

>> Это еще одна причина почему надо отрывать руки за использование этого типа.

Тогда за C/C++ и подобные языки всегда придётся отрывать руки, т.к. на разных платформах размеры встроенных типов не определяются стандартом. Тут wchar_t тоже не при чём совершенно.

Deleted
()
Ответ на: комментарий от Deleted

> Вы ошиблись, UTF-16 никак не может быть совместимо с char * (UTF-8).

Не utf-16 совместим, а QString совместим.

> В линуксе sizeof(wchar_t) == 4, в других юникс-подобных ОС подозреваю что так же. То есть длинна строки всегда равна количеству элементов wchar_t в ней.

Мы вроде про кроссплатформенность говорим. В стандарте Си ничего не написано про то, что sizeof(wchar_t) == 4.

Reset ★★★★★
()
Ответ на: комментарий от Reset

>> Не utf-16 совместим, а QString совместим.

Сорри, я вас видимо не понял. QString просто умеет сам конвертировать широкосимвольные строки в мультибайтовые.

>> Мы вроде про кроссплатформенность говорим. В стандарте Си ничего не написано про то, что sizeof(wchar_t) == 4.

В стандарте C/C++ ни про какой тип не написано какого он должен быть размера. И тем не менее на C/C++ как-то умудряются писать кроссплатформенные приложения.

Deleted
()
Ответ на: комментарий от Reset

> Стандартный Си идет лесом. glib есть везде (даже под visual studio) и нет ничего понятнее чем вот такая конструкция:

> for (char * p = s; *p; p = g_utf8_next_char(p)) { ... }

А где обработка некорректной последовательности байтов? И это приводит к следующей проблеме - надо везде думать - получена ли строка из надёжного источника или надо проверять её на корректность. В общем проблем хватает.

Legioner ★★★★★
()
Ответ на: комментарий от Reset

>> Есть типы с указанием размера. uint8_t, uint16_t, uint32_t, uint64_t и тоже самое без префикса u.

Дальше что? Ни в каком нормальном API они почти не используются. И это правильно.

Deleted
()
Ответ на: комментарий от Reset

>> При чем тут API ? Внутри структур данных такое еще как используется.

Да пусть используется дальше, я не понимаю какая тут связь с wchar_t?

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.