Как я могу встроить строковые константы Unicode в исходный файл? - PullRequest
10 голосов
/ 14 января 2009

Я пишу некоторые модульные тесты, которые будут проверять нашу обработку различных ресурсов, которые используют другие наборы символов, кроме обычного латинского алфавита: кириллица, иврит и т. Д.

Проблема в том, что я не могу найти способ встроить ожидания в исходный файл теста: вот пример того, что я пытаюсь сделать ...

///
/// Protected: TestGetHebrewConfigString
///  
void CPrIniFileReaderTest::TestGetHebrewConfigString()
{
    prwstring strHebrewTestFilePath = GetTestFilePath( strHebrewTestFileName );
    CPrIniFileReader prIniListReader( strHebrewTestFilePath.c_str() );
    prIniListReader.SetCurrentSection( strHebrewSubSection );   

    CPPUNIT_ASSERT( prIniListReader.GetConfigString( L"דונדארןמע" ) == L"דונהשךוק") );
}

Это просто не работает. Ранее я работал над этим, используя макрос, который вызывает подпрограмму для преобразования узкой строки в широкую (в наших приложениях мы используем towstring повсеместно, так что это существующий код)

#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 и обнаруживаю, что все тесты проваливаются: все это выглядит довольно хакерским. Может кто-нибудь сказать мне, если у них есть более хорошее решение этой проблемы?

Ответы [ 3 ]

18 голосов
/ 14 января 2009

Утомительный, но переносимый способ состоит в том, чтобы создавать свои строки, используя числовые escape-коды. Например:

wchar_t *string = L"דונדארןמע";

становится:

wchar_t *string = "\x05d3\x05d5\x05e0\x05d3\x05d0\x05e8\x05df\x05de\x05e2";

Вы должны преобразовать все ваши символы Юникода в числовые экранированные символы. Таким образом, ваш исходный код становится независимым от кодировки.

Вы можете использовать онлайн-инструменты для конвертации, такие как этот . Он выводит escape-формат JavaScript \uXXXX, поэтому просто найдите и замените \u на \x, чтобы получить формат C.

11 голосов
/ 14 января 2009

Вы должны указать 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.

0 голосов
/ 29 июня 2012
#define UNICODE_CONSTANT( CONSTANT ) towstring( CONSTANT )

wstring towstring( LPCSTR lpszValue ) {
    wostringstream os;
    os << lpszValue;
    return os.str(); 
}

На самом деле это вообще не конвертирует кодировки Unicode, что требует специальной процедуры. Вам необходимо сохранить единый исходный код и кодировки данных - большинство людей используют UTF-8, а затем при необходимости преобразовать их в кодировку, специфичную для ОС (например, UTF-16 в Winders).

...