将具有二进制字节序列的 std::string 转换为具有当前区域设置的字符集的 std::wstring

Convert std::string with a binary sequence of bytes into a std::wstring with character set from current locale

提问人:user2690527 提问时间:9/7/2015 更新时间:9/7/2015 访问量:433

问:

目前,我读取了两次相同的文件,因为我需要两种不同的表示形式:(a)没有任何转换的原始字节序列,(b)将字节转换为当前执行字符集的文本表示形式。基本上,代码如下所示:

using namespace std;
const char* fileName = "test.txt";

// Part 1: Read the file unmodified byte-per-byte
string binContent;
ifstream file1( fileName, ifstream::binary );
while( true ) {
    char c;
    file1.get( c );
    if( !file1.good() ) break;
    binContent.push_back( c );
}

// Part 2: Read the file and convert the character code according to the
// current locale from external character set to execution character set
wstring textContent;
wifstream file2( fileName );
wifstream.imbue( locale("") );
while( true ) {
    wchar_t c;
    file2 >> c;
    if( !file2.good() ) break;
    textContent.push_back( c );
}

显然,代码读取同一文件两次。我想避免这种情况并直接转换为内存。binaryContenttextContent

请注意,这不仅仅是一个普通的转换,因为如果当前区域设置的字符编码与执行字符编码不同,它还可能涉及真正的字符转换。这种转换可能是必要的,即使它也是一个狭窄的字符串。charwchar_tlocale("")textContent

在上面的示例中,第 2 部分中字符转换的魔力发生在 in 中,并涉及使用语言环境的方面。template<typename _CharT, typename _Traits> bool basic_filebuf<_CharT, _Traits >::_M_convert_to_external( _CharT* __ibuf, streamsize __ilen )fstream.tcccodecvt

我希望有一种方法可以从对象而不是对象构造对象,然后为对象注入适当的语言环境。但这似乎不起作用,因为所有构造函数都已经期望宽字符,似乎也没有实现 的转换逻辑。wistringstreambinContentwifsteamwistringstreamwistringstreamwistringstreamwifstream

有没有比手动使用更好的方法(即更简洁、更不容易出错)的方法?codecvt

C++ IOstream 字符串转换 WideString CodeCVT

评论


答: 暂无答案