簡體   English   中英

C ++問題,將wchar_t *轉換為字符串

[英]C++ Issue, Converting wchar_t* to string

我在這里有問題。 這是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轉換為wstring ,轉換為string 如果我取消注釋這兩行,則可以正常運行,並且消息框顯示正確。

有任何想法嗎? 在這里問這個問題是我的最后選擇。 謝謝。

這個說法:

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

讀取緩沖區中的第一line 好。

但是,在您的循環中,此語句:

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

在循環的頂部 ,因此在第一次迭代中丟棄了第一行,然后讀取了下一個line 最終,您的循環將到達緩沖區的末尾,並且wcstok()將返回NULL,但是在使用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

    //...
}

line = wcstok(NULL,L";"); 語句需要移到循環的底部

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

while (line != NULL)
{
    // use line as needed...

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

我建議將while循環更改為for循環以強制執行以下操作:

for (wchar_t* line = wcstok(readMap, L";"); (line != NULL); line = wcstok(NULL, L";"))
{
    // use line as needed...
}

另一方面,由於使用的是C ++,因此應考慮使用std:wistringstreamstd: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

該聲明將正常工作只有在std::wstring包含在#0 ASCII字符- #127范圍內。 對於非ASCII字符, 必須執行數據轉換,以避免Unicode字符> U + 00FF的數據丟失。

由於您在Windows上運行,因此可以使用Win32 API WideCharToMultiByte()函數:

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);
}

或者,如果您使用的是C ++ 11或更高版本,則可以使用std::wstring_convert類(不過僅適用於UTF-8 / 16/32轉換):

#include <locale> 

std::wstring line;
while (std::getline(iss, line, L';'))
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
    std::string str = conv.to_bytes(line);

    // use str as needed...
    MessageBoxW(0, line.c_str(), L"line", 0);
    MessageBoxA(0, str.c_str(), "str", 0);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM