C ++问题,将wchar_t *转换为字符串

时间:2015-09-16 01:00:41

标签: c++ unicode tokenize

我在这里遇到了问题。这是Unicode。我有一个包含值的字符串表,由;分隔。我整天都在这里,而且我总是会立即遇到运行时错误。

Stringtable看起来像:

`blah;blah;foo;bar;car;star`

然后是代码:

// More than enough size for this
const int bufferSize = 2048;

// Resource ID to a StringTable
int resid = IDS_MAP;
wchar_t readMap[bufferSize];            
resid = LoadString(NULL, resid, readMap, bufferSize);  

wchar_t* line;
line = wcstok(readMap,L";");

while (line != NULL) {

    line = wcstok(NULL,L";");
    wstring wstr(line); // Problem
    string str(wstr.begin(), wstr.end()); // Problem

    MessageBox(0,line,0,0) // No problem
}

问题是当我尝试将wchar_t* line转换为wstringstring时。如果我取消注释这两行,它运行正常并且消息框显示正确。

有什么想法吗?这里提出这个问题是我的最后一招。感谢。

1 个答案:

答案 0 :(得分:1)

本声明:

line = wcstok(readMap,L";");

读取缓冲区中的第一个分隔line。行。

但是,在你的循环中,这句话:

line = wcstok(NULL,L";");

位于循环的顶部,因此在第一次迭代中丢弃第一行,然后读取 next 分隔{ {1}}。最终,您的循环将到达缓冲区的末尾,line将返回NULL,但在使用wcstok()之前您没有检查该条件:

line

line = wcstok(readMap,L";"); // <-- reads the first line while (line != NULL) { line = wcstok(NULL,L";"); // <-- 1st iteration throws away the first line wstring wstr(line); // <-- line will be NULL on last iteration //... } 语句需要转移到循环的 bottom

line = wcstok(NULL,L";");

我建议将wchar_t* line = wcstok(readMap, L";"); while (line != NULL) { // use line as needed... line = wcstok(NULL, L";"); } 循环更改为while循环以强制执行:

for

另一方面,由于您使用的是C ++,因此应考虑使用for (wchar_t* line = wcstok(readMap, L";"); (line != NULL); line = wcstok(NULL, L";")) { // use line as needed... } std:wistringstream代替std:getline()

wcstok()

但不管怎样,这句话都是完全错误的:

#include <string>
#include <sstream>

// after LoadString() exits, resid contains the
// number of character copied into readMap...
std::wistringstream iss(std::wstring(readMap, resid));

std::wstring line;
while (std::getline(iss, line, L';'))
{
    // use line as needed...
}

仅当string str(wstr.begin(), wstr.end()); // Problem 包含#0 - #127范围内的ASCII字符时,此语句才能正确。对于非ASCII字符,您来执行数据转换,以避免Unicode字符的数据丢失&gt; U + 00FF。

由于您在Windows上运行,因此可以使用Win32 API std::wstring函数:

WideCharToMultiByte()

或者,如果您使用的是C ++ 11或更高版本,则可以使用std::wstring line; while (std::getline(iss, line, L';')) { std::string str; // optionally substitute CP_UTF8 with any ANSI codepage you want... int len = WideCharToMultiByte(CP_UTF8, 0, line.c_str(), line.length(), NULL, 0, NULL, NULL); if (len > 0) { str.resize(len); WideCharToMultiByte(CP_UTF8, 0, line.c_str(), line.length(), &str[0], len, NULL, NULL); } // use str as needed... MessageBoxW(0, line.c_str(), L"line", 0); MessageBoxA(0, str.c_str(), "str", 0); } 类(仅适用于UTF-8/16/32转换):

std::wstring_convert