Типографский апостроф + широкий строковый литерал нарушили мой wofstream (C ++)
-
03-07-2019 - |
Вопрос
Я только что столкнулся с некоторым странным поведением при работе со зловещим типографским апострофом ( ’ ), а не с апострофом пишущей машинки ( ' ).Используемый с широким строковым литералом, апостроф прерывает wofstream.
Этот код работает
ofstream file("test.txt");
file << "A’B" ;
file.close();
==> A’B
Этот код работает
wofstream file("test.txt");
file << "A’B" ;
file.close();
==> A’B
Этот код завершается с ошибкой
wofstream file("test.txt");
file << L"A’B" ;
file.close();
==> А
Этот код завершается с ошибкой...
wstring test = L"A’B";
wofstream file("test.txt");
file << test ;
file.close();
==> А
Есть какие - нибудь идеи ?
Решение
Вы должны "включить" локаль перед использованием wofstream:
std::locale::global(std::locale()); // Enable locale support
wofstream file("test.txt");
file << L"A’B";
Итак, если у вас есть системный языковой стандарт en_US.UTF-8
затем файл test.txt
будет включать
данные в кодировке utf8 (4 байта), если у вас есть системный язык en_US.ISO8859-1
, то он будет кодировать его как 8-битную кодировку (3 байта), если только ISO 8859-1 не пропускает такой символ.
wofstream file("test.txt");
file << "A’B" ;
file.close();
Этот код работает, потому что "A’B"
на самом деле это строка utf-8, и вы сохраняете utf-8
строка в файл байт за байтом.
Примечание: Я предполагаю, что вы используете POSIX как OS, и у вас языковой стандарт по умолчанию, отличный от "C", который является языковым стандартом по умолчанию.
Другие советы
Вы уверены, что "нарушена" не поддержка вашим компилятором символов юникода в исходных файлах?Что, если вы используете \x
или аналогично для кодирования символа в строковом литерале?Является ли ваш исходный файл даже в любой кодировке, которая может привести к wchar_t
для вашего компилятора?
Попробуйте обернуть символ вставки потока в try-catch
заблокируйте и сообщите нам, какое исключение оно выдает, если таковое имеется.
Я не уверен, что здесь происходит, но я все равно попытаюсь высказать предположение.Типографский апостроф, вероятно, имеет значение, которое умещается в один байт.Это работает с "A’B"
поскольку он слепо копирует байты, не беспокоясь о базовой кодировке.Однако, с L"A’B"
, вступает в игру фактор кодирования, зависящий от реализации.Вероятно, он не находит подходящее значение UTF-16 (если вы используете Windows) или UTF-32 (если вы используете * nix / Mac) для сохранения для этого конкретного символа.