日语系统中的字符转换不正确

Incorrect character conversion on Japanese systems

本文关键字:转换 不正确 字符 系统 日语      更新时间:2023-10-16

我有一个使用多字节字符集编译的项目。当消息1包含日语字符时,以下转换失败。

bool MyClass::UnfoldEnvelope(BSTR msg1)
{
    CW2A msg(msg1);
    LPCTSTR p0 = msg;
    ....
}

在输入时,msg1是一个BSTR,它包含unicode字符,并且有一个日语路径名。转换CW2A似乎在调用后工作,msg包含可识别的日语字符串。但是,LPCTSTR分配失败。在行之后,p0包含垃圾。字符串p0随后在我不愿意接触的旧代码中使用。

在这种情况下,获取指向字符串"msg"的指针的正确方法是什么?

在英语中一切都很好。

尝试使用WideCharToMultiByte!CP_ACP将宽字符串转换为当前Windows语言的单字节字符串(在日语Windows上可以是日语,CW2A也可以)。如果您的Windows不是日语,但有日语字符,则应使用CP_UTF8(UTF-8),并在使用(显示、打印或用作文件名)时将文本传输回UTF-16(wchar_t)。要转换回,您应该使用MultiByteToWideChar函数。

明确一点:ANSI多字节代码只是整个Unicode的一个子集。Windows使用与您的Windows位置相同的子集(您可以在"控制面板"中进行配置)。如果您有一个真正的Unicode字符串,或者不是基于区域设置的字符串,则应该将所有字符都保持在Unicode中。如果您想使用单字节字符串和Unicode,您应该将wchar_t字符串(所有Windows范围的字符都是UTF-16)转换为UTF-8 Unicode字符串。

检查此来源:

bool MyClass::UnfoldEnvelope(BSTR msg1) 
{
    // Get the necessary space for single byte string 
    int new_size = WideCharToMultiByte( CP_UTF8, 0, msg1, -1, NULL, NULL, NULL, NULL );
    if ( new_size <= 0 )
      return false;
    // Use vector to C functions
    vector<char> p0(new_size);
    // Convert the string
    if ( WideCharToMultiByte( CP_UTF8, 0, msg1, -1, &p0[0], new_size, NULL, NULL ) <= 0 )
    {
      return false;
    }
    // use string as a usual single byte string (save, load etc.)
    .... 
    // get the string size in UTF-16
    new_size = MultiByteToWideChar( CP_UTF8, 0, &p0[0], -1, NULL, NULL );
    if ( new_size <= 0 )
      return false;
    // Use vector to C functions
    vector<wchar_t> p1w(new_size);
    // convert back to UTF-16
    if ( MultiByteToWideChar( CP_UTF8, 0, &p0[0], -1, &p1w[0], new_size ) <= 0 )
      return false;
    ...
    // use your Unicode string as a file name
    return ( CopyFileW( L"old_file", &p1w[0], TRUE ) != FALSE );
}