Обновление:
Я решил, что не существует гарантированного способа сделать это. Решение, которое я представляю ниже, работает для английской версии VC2003, но не удается при компиляции с японской версией VC2003 (или, возможно, это японская ОС). В любом случае, это не может зависеть от работы. Обратите внимание, что даже объявление всего как строк "L" "не сработало (и это болезненно для gcc, как описано ниже).
Вместо этого я считаю, что вам просто нужно стиснуть зубы, переместить весь текст в файл данных и загрузить его оттуда. Сейчас я храню и получаю доступ к тексту в файлах INI через SimpleIni (кросс-платформенная библиотека INI-файлов). По крайней мере, есть гарантия, что он работает, поскольку весь текст находится вне программы.
Оригинал:
Я отвечаю на это сам, так как только Эван, казалось, понял проблему. Ответы относительно того, что такое Юникод и как использовать wchar_t, не имеют отношения к этой проблеме, так как речь не идет об интернационализации или неправильном понимании кодировки символов Юникода. Я ценю вашу попытку помочь, извините, если я не достаточно ясно.
Проблема в том, что у меня есть исходные файлы, которые нужно кросс-компилировать на различных платформах и компиляторах. Программа выполняет обработку UTF-8. Это не заботится о любых других кодировках. Я хочу иметь строковые литералы в UTF-8, как в настоящее время работает с gcc и vc2003. Как мне сделать это с VC2008? (т.е. обратно совместимое решение).
Вот что я нашел:
gcc (v4.3.2 20081105):
- строковые литералы используются как есть (необработанные строки)
- поддерживает исходные файлы в кодировке UTF-8
- исходные файлы не должны иметь спецификацию UTF-8
VC2003:
- строковые литералы используются как есть (необработанные строки)
- поддерживает исходные файлы в кодировке UTF-8
- исходные файлы могут иметь или не иметь спецификацию UTF-8 (это не имеет значения)
VC2005 +:
- строковые литералы массируются компилятором (без необработанных строк)
- литералы строки символов перекодируются в указанную локаль
- UTF-8 не поддерживается в качестве целевой локали
- исходные файлы должны иметь спецификацию UTF-8
Итак, простой ответ заключается в том, что для этой конкретной цели VC2005 + не работает и не предоставляет обратно совместимый путь компиляции. Единственный способ получить строки Unicode в скомпилированную программу - через UTF-8 + BOM + wchar, что означает, что мне нужно преобразовать все строки обратно в UTF-8 во время использования.
Нет простого кроссплатформенного метода преобразования wchar в UTF-8, например, в какой размер и кодировку входит wchar? На Windows, UTF-16. На других платформах? Различается. Подробности см. В проекте ICU .
В итоге я решил, что буду избегать затрат на конвертацию на всех компиляторах, кроме vc2005 + с источником, подобным следующему.
#if defined(_MSC_VER) && _MSC_VER > 1310
// Visual C++ 2005 and later require the source files in UTF-8, and all strings
// to be encoded as wchar_t otherwise the strings will be converted into the
// local multibyte encoding and cause errors. To use a wchar_t as UTF-8, these
// strings then need to be convert back to UTF-8. This function is just a rough
// example of how to do this.
# define utf8(str) ConvertToUTF8(L##str)
const char * ConvertToUTF8(const wchar_t * pStr) {
static char szBuf[1024];
WideCharToMultiByte(CP_UTF8, 0, pStr, -1, szBuf, sizeof(szBuf), NULL, NULL);
return szBuf;
}
#else
// Visual C++ 2003 and gcc will use the string literals as is, so the files
// should be saved as UTF-8. gcc requires the files to not have a UTF-8 BOM.
# define utf8(str) str
#endif
Обратите внимание, что этот код является просто упрощенным примером. Производственное использование потребовало бы его очистки различными способами (безопасность потоков, проверка ошибок, проверка размера буфера и т. Д.).
Используется как следующий код. В моих тестах на gcc, vc2003 и vc2008 он корректно компилируется и работает правильно:
std::string mText;
mText = utf8("Chinese (Traditional)");
mText = utf8("中国語 (繁体)");
mText = utf8("중국어 (번체)");
mText = utf8("Chinês (Tradicional)");