LINUX.ORG.RU

Избранные сообщения dataman

c++ и utf-8

Форум — Development

Допустим есть файл сохранённый в UTF8. Читать я его могу исключительно std::ifstream (без std::wifstream).

После прочтения файла, я хочу иметь возможность итерироваться по utf-8 символам, и даже сравнивать их

for (size_t i = 0; i < utf8String.size(); i++) {
    if (utf8String[i] == 'ф') {
        //...
    }
}

Т.е. я хочу чтобы была возможность работать с каждым utf-8 символом, в независимости от того какой он длинны как с одним символом.

Что мне для этого нужно?

Я думал что wchar_t. Но есть такие два источника: 1. https://ru.wikipedia.org/wiki/Широкий_символ 2. https://stackoverflow.com/questions/17871880/should-i-use-wchar-t-when-using-...

Которые вроде как говорят что это не очень хорошо.

Еще я заметил (да на ++ уже пишу и не первый год), но заметил только сейчас, т.к.раньше просто не думал про это ибо не было нужно:

что std::wstring wstr = L"добро"; //да, система дебиан 8, x86-64, исходник сохранен в utf8.

в общем wstr==«добро» в оперативной памяти будет представлено не в utf-8 а в неведомой кодировке. Но по которой можно итерироваться и сравнивать.

Буква 'д' из этой строки будет иметь следующий байт-код 00110100 00000100 00000000 00000000 (wchar_t)

При этом если бы 'д' была в utf8 то она должна была бы иметь такие байты 11010000 10110100 {00000000 00000000} - в скобках хвост который как бы не имеет отношение к коду 'д', но заполняет тип wchar_t.

Вопросы: Можно ли как-то сделать так чтобы компилятор (g++) видя wchar_t c = L'д' или whchar_t c = 'д' - конструировал utf8 букву в wchar_t типе, а не в непонятной кодировке. И кстати в какой кодировке он её кодирует по умолчанию?

Есть ли какой-то способ прочитать преобразовать utf-8 строку, хранимую в std::string в std::wstring так чтобы после такого преобразования содержимое этой wstring можно было бы корректно вывести в std::wcout?

Я нашел такой способ Преобразование std::string в std::wstring

Но во первых он какой-то страншный и не очень понятный, какие-то шаблоны актуализируются...

А самое главное в моём debian8 и gcc4.3 нет такого хедера include <codecvt>

Поэтому у кого поновее пакетная база, и кому не лень, пожалуйста из ссылки выше запустите пример. Сделайте std::string str(«добро») и преобразуйте её в std::wstring Нужно чтобы после преобразования wstring строка корректно выводилась в std::wcout и можно было побуквенно (а не побайтово) итерироваться по ней, и посимвольно сравнивать.

В общем, т.к. у меня нет этого codecvt я сделал преобразование руками (да можно красивее, переносимее (учитывать порядок байт), при вызове из main не выходить за границы строки и т.д. и т.п. - не суть): https://pastebin.com/4E3nuNcM

и вот если приблизительно таким методом конструировать std::wstring которая содержит utf-8 можно будет итерироваться по ней (да, я знаю что utf8 может быть длиннее чем размер wchar_t, но у меня будет набор латиницы и кириллицы из utf8 документа), можно будет сравнивать с символами, но к сожалению не так wstr[0] = 'ы' а только с заранее созданными символами, подобным методом как строка создавалась. wstr[0] == wcharSymbol.

Это не удобно, а еще такая строка не может корректно выводится на std::wcout.

Т.е. заключительный вопрос - можно ли как-то пользуя нативный wchar_t работать посимвольно с utf-8 в c++ в линукс, имея полный ф-л такой как итерации, посимвольное сравнение, корректный вывод в std::wcout.

Если нельзя - есть ли возможно какие-то сторонние (причем легковесные библиотеки, код которых можно включить в проект, и собрать статически, и чтобы места не много тратили) которые предоставляют некий тип wideChar, полностью совместимый и с std::wcout и со всей stl(конейнерами, алгоритмами) и при этом желательно кросплатформенная?

Кстати в презренной винде на этом же наборе символов utf8 (латиница и кириллица) - всё очень хорошо (плохо там будет когда потребуется символ длиннее 2 байт) - т.к. там wchar_t это 2 байта, т.е. он как раз отлично соотвествует, и в wcout тоже выводится :)

Просьба не флудить а по конкретике писать :)

 , , , ,

bonta
()

utf-8/16 библиотеки для Си

Форум — Development

Пилю тихонько веб-сервис на kore.io и сейчас стал нужен шаблонизатор пока что пишу его прототип ясен пень что он тоже на Си. База будет в utf-8, кодировка html выхлопа тоже utf-8,пользовательские данные через POST тоже могут быть utf-8, пока пишу прототип не парюсь и всё обрабатывается просто как char*. Но так как никогда вплотную не работал с utf-8 боюсь граблей от переменной длинны символов. Если есть что по теме посоветовать, буду рад почитать.

Ну и по традиции cast сишников DELIRIUM, i-rinat, beastie, ncrmnt, Iron_Bug.

UDP: Довольно забавное чтиво, отражающее «всю» красоту работы с utf-8 :D https://gist.github.com/outpunk/1956399

UDP2: я ненавижу unicode

UDP3: не так страшен чёрт как его малюют utf8+char=❤

UDP4: Агрегирую всё нижесказанное и дополнительные ссылки которые могут быть полезны залётным падаванам ::)

Что-бы понять как оно в памяти лежит.

  • Перво наперво => wikipediaUTF-8

wchar_t - если хотите любой символ хранить и юзаете только системы где он 32 бита то пожалуйста, но помните даже utf-8 текст очень часто на 90% состоит из набора ASCII который занимает 1 байт и просто так увеличивать размер текста в четверо заимея лишь возможность безболезненно прыгать по нормализованным символам, ну не знаю, вам решать, можно но не нужно.

  • Код от a1batross за авторством mittorn полезно для понимания как сдвинуть символ, как перевести в другую кодировку и прочее
  • libutf Предложенный beastie предоставляет функции для насущных нужд
    typedef int32_t Rune;
    Rune *runestrcat(Rune *, const Rune *);
    Rune *runestrncat(Rune *, const Rune *, size_t);
    int runestrcmp(const Rune *, const Rune *);
    int runestrncmp(const Rune *, const Rune *, size_t);
    Rune *runestrcpy(Rune *, const Rune *);
    Rune *runestrncpy(Rune *, const Rune *, size_t);
    size_t runestrlen(const Rune *);
    Rune *runestrchr(const Rune *, Rune);
    Rune *runestrrchr(const Rune *, Rune);
    Rune *runestrdup(const Rune *);
    Rune *runestrstr(const Rune *, const Rune *);
    //и прочие не менее полезные
    
  • utf8proc от проекта языка julia написана на С и создана для жизненно необходимой нормализации utf-8.
    ** NFD normalization (@ref UTF8PROC_DECOMPOSE). */
    UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str);
    /** NFC normalization (@ref UTF8PROC_COMPOSE). */
    UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str);
    /** NFKD normalization (@ref UTF8PROC_DECOMPOSE and @ref UTF8PROC_COMPAT). */
    UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str);
    /** NFKC normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT). */
    UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str);
    
  • iconv или ICU перекодировка и манипуляция с unicode и другими кодировками
  • glib utf-8/16, содержит практически всё что нужно
  • i-rinal дал очень полезную штуку в которой описаны псевдонимы кодировок, кодировка одна а названий её десяток =)
  • waker предложил свою библиотеку для манимуляций с utf-8, стоит отметить разнообразие функций и скорость.
  • Анон пнул в матчасть =) отдельное спасибо
  • mittorn поделился ссылочкой декодера и ещё одного

Ну и вроде как всё, на последок просто ссылок

https://habrahabr.ru/post/45489/ https://habrahabr.ru/post/311518/ https://ru.wikipedia.org/wiki/UTF-16 http://unicodebook.readthedocs.io/programming_languages.html http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm https://ru.wikipedia.org/wiki/Широкий_символ http://www.cl.cam.ac.uk/~mgk25/unicode.html#c https://habrahabr.ru/post/138173/

 , ,

Deleted
()

Порекомендую хорошую книгу по электронике

Форум — Talks

Practical Electronics for Inventors. Купил, читаю и очень доволен. На английском языке. Вроде есть русское издание от BHV, его не читал. Объясняется очень доступно, без заумностей. Но в то же время с нужными формулами, есть разделы, где объясняется физика явлений для желающих. Английский довольно простой, я его знаю так себе, но проблем с чтением не возникло.

Оно продаётся в электронном виде, если денег жалко, наверняка есть рипы на торрентах. У меня версия с DRM, к сожалению поделиться не смогу.

 , ,

Legioner
()

Оффтопик-лист (изменён 03.09.2025)

Форум — Linux-org-ru
  1. Темы о Windows и Microsoft, не имеющие отношения к FOSS.
  2. Новости о намерениях что-либо делать (переходить на Linux и т.п.). Вот сделают, тогда и обсудим. По просьбам пользователей.
  3. Новости о бетах и RC ядра Linux или другого ПО без каких-либо серьёзных или интересных изменений (если бета или RC не судьбоносен по какой-то причине, например, проект не подавал признаков жизни год).
  4. Новости о новых выпусках журналов. По просьбам пользователей.
  5. Новости, полностью скопированные с других ресурсов. Предупреждая новые и следуя существующим пожеланиям владельцев ресурсов, за исключением случаев, когда такое копирование одобрено владельцами ресурсов.
  6. Новости о неизвестных и не оригинальных дистрибутивах.
  7. Новости про UALinux и их дистрибутивах.
  8. Вопросы «почему забанен или заморожен $username?». Во избежание бессмысленных флеймов и провокаций. Сама причина бана или заморозки указывается в профиле. Не относится к самозабану.
  9. Ссылки на порнографические материалы и фотоматериалы по медицине или судмедэкспертизе без разрешения модераторов.
  10. Обсуждение, есть ли среди модераторов виртуалы. Виртуалов нет.
  11. Обсуждение медицинских препаратов, изменяющих сознание, БАД, наркотических веществ, стимуляторов и тому подобных, кроме случаев вопросов по фильтрации спама.
  12. Обсуждение опечаток или грамматических и орфографических ошибок в тексте или тегах новости, статьи или скриншота вне специально созданной для этого темы. Пожалуйста, используйте для этого уведомление модераторов с указанием проблемы в ОП «Опечатка или форматирование».
  13. «Падонковский» или «двачерский» сленг, если он преобладает в сообщении.
  14. Перепечатка «шокирующих новостей» с Дней, Фогньюза, Лапши, autonews.ru и других сайтов, публикующих якобы «важные» (Дни, autonews) новости или заведомо ложную информацию (фог, лапша).
  15. Новости с любых ресурсов Арама Габрелянова.
  16. Вопросы в духе «работает ли у вас ресурс такой-то». Проверить, упал ли какой-то ресурс можно на isup.me. Проверить блокировку ресурса можно на isitblockedinrussia.com
  17. Комментарии в духе «не нужно», не несущие смысловой нагрузки (используйте реакцию).
  18. Зловредный код.
  19. Обсуждение сексуальной ориентации кого бы то ни было.
  20. Ноги, ногти и вопросы питания RMS (Richard Matthew Stallman).
  21. отменён
  22. Внешние ссылки, для просмотра которых требуется регистрация.
  23. «Сокращаторы» ссылок.
  24. Видео, на которых собаки или другие животные имитируют половой акт с людьми.
  25. Обсуждение вакцинации от Covid-19 и вакцин.
  26. Средства обхода блокировок; применение и выбор VPN для обхода блокировок.

 

Shaman007
()

Количество и качество активных гаджетов в семье / квартире?

Голосования — Голосования

Стало вдруг интересно, надеюсь, никого не повторил. Количество можно озвучить по желанию.

  1. Смартфон 496 (91%)

    ********************************************************************************************************************************************************************************************************************************************************************************************************************************

  2. Ноутбук 474 (87%)

    *****************************************************************************************************************************************************************************************************************************************************************************************************************

  3. ПК 418 (77%)

    *****************************************************************************************************************************************************************************************************************************************************************************

  4. Телевизор (их же до сих пор так зовут?) 311 (57%)

    ********************************************************************************************************************************************************************************************************

  5. Планшет 241 (44%)

    ***********************************************************************************************************************************************************

  6. Домашний сервер 160 (29%)

    *******************************************************************************************************

  7. Одноплатник (RPi etc) 155 (28%)

    ****************************************************************************************************

  8. Мобильный телефон 122 (22%)

    ******************************************************************************

  9. Игровая приставка 119 (22%)

    ****************************************************************************

  10. Медиаприставка 106 (19%)

    ********************************************************************

  11. NAS 86 (16%)

    *******************************************************

  12. Нетбук 84 (15%)

    ******************************************************

  13. Другое 54 (10%)

    **********************************

  14. PDA 14 (3%)

    *********

Всего голосов: 2840, всего проголосовавших: 544

 , ,

slimblyandysh
()