Как записать std::string в текстовый файл UTF-8
Я просто хочу написать несколько простых строк в текстовый файл на C++, но я хочу, чтобы они были закодированы в UTF-8. Какой самый простой и простой способ сделать это?
9 ответов
Единственный способ, которым UTF-8 влияет std::string
в том, что size()
, length()
и все индексы измеряются в байтах, а не в символах.
И, как указывает sbi, увеличивая итератор, предоставленный std::string
будет шаг вперед по байту, а не по символу, поэтому он может фактически указывать на середину многобайтовой кодовой точки UTF-8. В стандартной библиотеке нет итератора с поддержкой UTF-8, но есть несколько доступных в сети.
Если вы помните это, вы можете поместить UTF-8 в std::string
, запишите его в файл и т. д. все в обычном порядке (под этим я подразумеваю то, как вы std::string
без UTF-8 внутри).
Возможно, вы захотите начать свой файл с метки порядка байтов, чтобы другие программы знали, что это UTF-8.
Есть хорошая маленькая библиотека для работы с utf8 из C++: utfcpp
libiconv - отличная библиотека для всех наших потребностей в кодировании и декодировании.
Если вы используете Windows, вы можете использовать WideCharToMultiByte и указать, что вы хотите UTF8.
Какой самый простой и простой способ сделать это?
Самая интуитивно понятная и, следовательно, самая простая обработка utf8 в C++ наверняка использует замену дляstd::string
, Так как в интернете его еще нет, я решил реализовать эту функцию самостоятельно:
tinyutf8 (РЕДАКТИРОВАТЬ: теперь Github).
Эта библиотека предоставляет очень легкую вставку для std::string
(или же std::u32string
если хотите, потому что вы перебираете кодовые точки, а не символы s). Ity успешно реализован в середине между быстрым доступом и небольшим потреблением памяти, при этом будучи очень надежным. Эта устойчивость к "недопустимым" UTF8-последовательностям делает его (почти полностью) совместимым с ANSI (0-255).
Надеюсь это поможет!
Если под "простым" вы подразумеваете ASCII, нет необходимости выполнять какую-либо кодировку, так как символы со значением ASCII 127 или менее одинаковы в UTF-8.
std::wstring text = L"Привет";
QString qstr = QString::fromStdWString(text);
QByteArray byteArray(qstr.toUtf8());
std::string str_std( byteArray.constData(), byteArray.length());
Я предпочитаю конвертировать в и из std::u32string и работать с внутренними кодовыми точками, а затем конвертировать в utf8 при записи в файл, используя эти итераторы преобразования, которые я установил на github.
#include <utf/utf.h>
int main()
{
using namespace utf;
u32string u32_text = U"ɦΈ˪˪ʘ";
// do stuff with string
// convert to utf8 string
utf32_to_utf8_iterator<u32string::iterator> pos(u32_text.begin());
utf32_to_utf8_iterator<u32string::iterator> end(u32_text.end());
u8string u8_text(pos, end);
// write out utf8 to file.
// ...
}
Используйте Glib::ustring из glibmm.
Это единственный распространенный контейнер для струнных UTF-8 (AFAIK). Хотя глиф (не байтовый) основан, он имеет те же сигнатуры метода, что и std::string
так что порт должен быть простым поиском и заменой (просто убедитесь, что ваши данные являются действительными UTF-8, прежде чем загружать их в ustring
).
Что касается UTF-8, то это строка многобитных символов, поэтому у вас возникают некоторые проблемы, и это плохая идея. Вместо этого используйте обычный Unicode.
Поэтому, на мой взгляд, лучше всего использовать обычный текст ASCII-символов с некоторым набором кодировок. Необходимо использовать Unicode, если вы используете более 2 наборов различных символов (языков) в одном.
Это довольно редкий случай. В большинстве случаев достаточно 2 набора символов. Для этого распространенного случая используйте символы ASCII, а не Unicode.
Эффект от использования мультибутовых символов, таких как UTF-8, вы получаете только в китайском традиционном, арабском или каком-то иероглифическом тексте. Это очень, очень редкий случай!!!
Я не думаю, что это нужно многим людям. Так что никогда не используйте UTF-8!!! Это позволяет избежать сильной головной боли манипулировать такими строками.