2010-06-10 3 views
47

Я просто хочу написать несколько простых строк в текстовом файле на C++, но я хочу, чтобы они были закодированы в UTF-8. Какой самый простой и простой способ сделать это?Как написать std :: string в текстовый файл UTF-8

+11

Безумно, что библиотека std не может иметь дело с utf-8. Вот почему мы должны обрабатывать тонны конверсий между широкими строками и байтовыми строками с некоторой неудобной локалью. Почему после всех этих лет нет ничего подобного std :: utf8string? –

+4

, потому что C/C++ должны быть совместимы с несуществующим оборудованием? : P – GameDeveloper

ответ

9

libiconv - отличная библиотека для всех наших потребностей в кодировании и декодировании.

Если вы используете Windows, вы можете использовать WideCharToMultiByte и указать, что хотите UTF8.

7

Если «простой» означает ASCII, нет необходимости делать какую-либо кодировку, так как символы с ASCII значением 127 или менее одинаковы в UTF-8.

+1

Я предполагаю, что у него есть другие персонажи, хотя ему нужна кодировка, которую он хранит внутри своей строки. Но, возможно, нет :) –

50

Единственный способ, которым UTF-8 влияет на std::string, заключается в том, что size(), length(), и все индексы измеряются в байтах, а не в символах.

И, как указывает sbi, приращение итератора, предоставляемое std::string, будет перемещаться по байту, а не по символу, поэтому оно может фактически указывать на середину многобайтового кодового пункта UTF-8. В стандартной библиотеке нет итератора, поддерживающего UTF-8, но есть несколько доступных в «Сети».

Если вы помните это, вы можете поместить UTF-8 в std::string, записать его в файл и т. Д. Все обычным способом (под которым я подразумеваю способ использования std::string без UTF-8 внутри) ,

Возможно, вы захотите запустить свой файл с байтом, чтобы другие программы знали, что это UTF-8.

+2

Для полноты добавьте итераторы к первому предложению, это то же самое с ними, что и с индексами. – sbi

+14

Многие программы задыхаются от спецификации, когда читают UTF-8, и это заставит некоторые программы думать, что текст UTF-16. –

+1

@TimSeguine: Это просто длинный способ сказать, что многие программы не имеют или очень плохо поддерживают UTF-8. –

20

Существует хорошая крошечная библиотека для работы с utf8 из C++: utfcpp

+2

Uao - самая крутая библиотека. Учитывая, что вы знаете, что такое UTF8, вам больше ничего не нужно. – GameDeveloper

5
std::wstring text = L"Привет"; 
QString qstr = QString::fromStdWString(text); 
QByteArray byteArray(qstr.toUtf8());  
std::string str_std(byteArray.constData(), byteArray.length()); 
+10

Примечание: для этого кода требуется [Qt toolkit] (https://qt-project.org/). – michaelb958

-28

Как UTF-8 является multibite символов строки, и поэтому вы получаете некоторые проблемы, работать, и это плохая идея/Вместо этого используйте нормальный Unicode.

Так что, по моему мнению, лучше всего использовать обычный текст символа ASCII с некоторым набором кодировок. Необходимо использовать Unicode, если вы используете более двух наборов разных символов. (языки) в одном.

Это довольно редкий случай. В большинстве случаев достаточно 2 наборов символов. Для этого общего случая используйте символы ASCII, а не Unicode.

Эффект использования многообразных символов, таких как UTF-8, вы получаете только традиционный китайский, арабский или иероглифический текст. Это очень редкий случай !!!

Я не думаю, что это нужно многим народам. Поэтому никогда не используйте UTF-8 !!! Это позволяет избежать сильной головной боли при манипулировании такими струнами.

+4

Что именно вы подразумеваете под «нормальным Unicode»? Я собираюсь предположить, что вы имеете в виду, что большинство программистов на Java и Windows считают, что Unicode означает: UTF16. Это также не кодирование с постоянной шириной (не каждый символ занимает ровно 2 байта). Примерно половина пользователей Интернета - из Китая. Очень редкий! –

+2

@Anatoly - некоторые справочные материалы: http://www.joelonsoftware.com/articles/Unicode.html, http://www.theregister.co.uk/2013/10/04/verity_stob_unicode/, http: // www .utf8everywhere.org /. Если вы только прочитали, прочитайте первый из них. Вы можете изменить свою рекомендацию, чтобы никогда не использовать UTF-8! –

+2

Причина использования utf-8 заключается в том, что он может кодировать все кодовые точки Unicode и что он эффективен для памяти на латинских языках. Недостатком является то, что вы кодируете переменную длину. Обратите внимание, что существует различие между utf-16 и ucs-2. Ucs-2 - это тот, который вы упоминаете: фиксированный 2 байта на символ, но в качестве недостатка, что он не может кодировать все кодовые точки. – gast128

8

Что является самым простым и простым способом?

Наиболее интуитивная и, таким образом, простая обработка utf8 в C++ наверняка с помощью раскрывающегося заменителя std::string. Поскольку в Интернете по-прежнему не хватает одного, я начал реализовывать свои функции самостоятельно:

tinyutf8 (EDIT: теперь Github).

Эта библиотека обеспечивает очень легкие раскрывающуюся в preplacement для std::string (или std::u32string, если вы будете, потому что вы перебрать скорее кодовые что символа ы). Ity успешно внедряется в середине между быстрым доступом и небольшим объемом памяти, будучи очень надежным. Эта устойчивость к «недействительным» UTF8-последовательностям делает его (почти полностью) совместимым с ANSI (0-255).

Надеюсь, это поможет!

+0

Ваша библиотека выглядит неплохо, но ее лицензия очень ограничена. –

+0

Каким образом это ограничивает? Какую лицензию вы хотите, чтобы я опубликовал ее? –

+1

GPL означает, что если я включу ваш заголовок в свою программу, я должен также сделать свою программу GPL. Довольно ограничивать, не так ли? Я бы рекомендовал BSD стиль лицензии для небольшой библиотеки, как это. –

0

Использование Glib::ustring от glibmm.

Это единственный широко распространенный контейнер строки UTF-8 (AFAIK). Хотя на основе глифа (не байт) он имеет такие же сигнатуры метода, что и std::string, поэтому порт должен быть простым поиском и заменой (просто убедитесь, что ваши данные действительны UTF-8 перед загрузкой в ​​ustring).

Смежные вопросы