代码之家  ›  专栏  ›  技术社区  ›  jkp

如何在源文件中嵌入Unicode字符串常量?

  •  10
  • jkp  · 技术社区  · 16 年前

    我正在编写一些单元测试,这些测试将验证我们对各种资源的处理,这些资源使用除正常拉丁字母之外的其他字符集:西里尔语、希伯来语等。

    我遇到的问题是,我找不到一种方法将期望嵌入到测试源文件中:下面是一个我正在尝试做的事情的示例…

    ///
    /// 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( "דונהשךוק" ) );
    

    这在OSX上运行正常,但是现在我要移植到Linux,我发现测试都失败了:所有的测试都感觉很黑客。有人能告诉我他们是否能更好地解决这个问题吗?

    3 回复  |  直到 12 年前
        1
  •  18
  •   Stabledog Tom Ekberg    12 年前

    一种冗长但可移植的方法是使用数字转义码构建字符串。例如:

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

    变成:

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

    必须将所有Unicode字符转换为数字转义。这样,源代码就变得与编码无关。

    您可以使用在线工具进行转换,例如 this one . 它输出JavaScript转义格式 \uXXXX ,因此只需搜索和替换 \u 具有 \x 获取C格式。

        2
  •  11
  •   Johannes Schaub - litb    16 年前

    您必须告诉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 海湾合作委员会使用。

    你可以调整它。该选项主要用于编译 wine 与Windows兼容。该选项被调用 -fshort-wchar ,并且很可能是16位而不是32位,这是在Linux上gcc通常的宽度。

    这些选项在 man gcc ,GCC手册页。

        3
  •  0
  •   Puppy    12 年前
    #define UNICODE_CONSTANT( CONSTANT ) towstring( CONSTANT )
    
    wstring towstring( LPCSTR lpszValue ) {
        wostringstream os;
        os << lpszValue;
        return os.str(); 
    }
    

    这实际上根本不需要在Unicode编码之间进行转换,这需要一个专用的例程。您需要保持源代码和数据编码的统一(大多数人使用UTF-8),然后在必要时将其转换为特定于操作系统的编码(例如,winders上的UTF-16)。