Я пишу несколько модульных тестов, которые проверят нашу работу с различными ресурсами, которые используют другие наборы символов, кроме обычного латинского алфавита: кириллица, иврит и т. д.
У меня проблема в том, что я не могу найти способ встроить ожидания в исходный файл теста: вот пример того, что я пытаюсь сделать ...
///
/// Protected: TestGetHebrewConfigString
///
void CPrIniFileReaderTest::TestGetHebrewConfigString()
{
prwstring strHebrewTestFilePath = GetTestFilePath( strHebrewTestFileName );
CPrIniFileReader prIniListReader( strHebrewTestFilePath.c_str() );
prIniListReader.SetCurrentSection( strHebrewSubSection );
CPPUNIT_ASSERT( prIniListReader.GetConfigString( L"דונדארןמע" ) == L"דונהשךוק") );
}
Это просто не работает. Раньше я работал над этим, используя макрос, который вызывает процедуру для преобразования узкой строки в широкую (мы используем буксирную строку повсюду в наших приложениях, поэтому это существующий код)
#define UNICODE_CONSTANT( CONSTANT ) towstring( CONSTANT )
wstring towstring( LPCSTR lpszValue )
{
wostringstream os;
os << lpszValue;
return os.str();
}
Утверждение в приведенном выше тесте стало:
CPPUNIT_ASSERT( prIniListReader.GetConfigString( UNICODE_CONSTANT( "דונדארןמע" ) ) == UNICODE_CONSTANT( "דונהשךוק" ) );
Это работало нормально на OS X, но теперь я портирую на Linux и обнаруживаю, что все тесты не работают: все это тоже кажется довольно хакерским. Может ли кто-нибудь сказать мне, есть ли у них более хорошее решение этой проблемы?





Вы должны указать GCC, какую кодировку использует ваш файл для кодирования этих символов в файл.
Используйте опцию -finput-charset=charset, например -finput-charset=UTF-8. Затем вам нужно сообщить ему о кодировке, используемой для этих строковых литералов во время выполнения. Это определит значения элементов wchar_t в строках. Вы устанавливаете эту кодировку с помощью -fwide-exec-charset=charset, например -fwide-exec-charset=UTF-32. Помните, что размер кодировки (для utf-32 требуется 32 бита, для utf-16 требуется 16 бит) не должен превышать размер wchar_t, который использует gcc.
Вы можете это отрегулировать. Эта опция в основном полезна для компиляции программ для wine, совместимых с Windows. Параметр называется -fshort-wchar, и, скорее всего, он будет 16-битным вместо 32-битного, что является его обычной шириной для gcc в Linux.
Эти параметры более подробно описаны в man gcc, справочной странице gcc.
Утомительный, но переносимый способ - создавать строки с использованием числовых escape-кодов. Например:
wchar_t *string = L"דונדארןמע";
становится:
wchar_t *string = "\x05d3\x05d5\x05e0\x05d3\x05d0\x05e8\x05df\x05de\x05e2";
Вам нужно преобразовать все ваши символы Unicode в числовые escape-символы. Таким образом, ваш исходный код становится независимым от кодировки.
Вы можете использовать онлайн-инструменты для конвертации, такие как Вот этот. Он выводит escape-формат JavaScript \uXXXX, поэтому просто найдите и замените \u на \x, чтобы получить формат C.
Нет ограничений на количество шестнадцатеричных цифр после \ x, поэтому это должно работать одинаково независимо от размера (wchar_t). См. Эту тему для получения дополнительной информации: stackoverflow.com/questions/2735101/unicode-escaping-in-c-c
#define UNICODE_CONSTANT( CONSTANT ) towstring( CONSTANT )
wstring towstring( LPCSTR lpszValue ) {
wostringstream os;
os << lpszValue;
return os.str();
}
На самом деле это не приводит к преобразованию между кодировками Unicode, для чего требуется специальная процедура. Вам необходимо сохранить единый исходный код и кодировки данных - большинство людей используют UTF-8-, а затем при необходимости преобразовать это в кодировку, специфичную для ОС (например, UTF-16 на Winders).
В Windows wchar_t - 16 бит, а все остальные - 32 бита. Влияет ли это на то, какие шестнадцатеричные литералы необходимо перечислить? Или
\x05d3одинаково хорошо работает и на 16, и на 32 бит?