2016-07-01 40 views
2

文字列をLPCWSTRに変換しようとしています(マルチバイトを使用しています)。例えばLPCWSTRの文字列をC++で

1)

LPCWSTR ToLPCWSTR(string text) 
{ 
    LPCWSTR sw = (LPCWSTR)text.c_str(); 
    return sw; 
} 

2)これは、中国語の文字を返し:

LPCWSTR ToLPCWSTR(string text) 
{ 
    std::wstring stemp = std::wstring(text.begin(), text.end()); 
    LPCWSTR sw = (LPCWSTR)s.c_str(); 
    return sw; 
} 

しかしながら、それらの両方が常に正方形を示す:

Image

{EDITED}によって編集と マイコード:Barmak Shemirani

std::wstring get_utf16(const std::string &str, int codepage) 
{ 
    if (str.empty()) return std::wstring(); 
    int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0); 
    std::wstring res(sz, 0); 
    MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz); 
    return res; 
} 

string HttpsWebRequest(string domain, string url) 
{ 
    LPCWSTR sdomain = get_utf16(domain, CP_UTF8).c_str(); 
    LPCWSTR surl = get_utf16(url, CP_UTF8).c_str(); 
    //(Some stuff...) 
} 

リターン: https://i.gyazo.com/ea4cd50765bfcbe12c763ea299e7b508.png

{EDITED} UTF16をUTF8から渡す別のコードを使用して、依然として同じ結果。

std::wstring utf8_to_utf16(const std::string& utf8) 
{ 
    std::vector<unsigned long> unicode; 
    size_t i = 0; 
    while (i < utf8.size()) 
    { 
     unsigned long uni; 
     size_t todo; 
     bool error = false; 
     unsigned char ch = utf8[i++]; 
     if (ch <= 0x7F) 
     { 
      uni = ch; 
      todo = 0; 
     } 
     else if (ch <= 0xBF) 
     { 
      throw std::logic_error("not a UTF-8 string"); 
     } 
     else if (ch <= 0xDF) 
     { 
      uni = ch & 0x1F; 
      todo = 1; 
     } 
     else if (ch <= 0xEF) 
     { 
      uni = ch & 0x0F; 
      todo = 2; 
     } 
     else if (ch <= 0xF7) 
     { 
      uni = ch & 0x07; 
      todo = 3; 
     } 
     else 
     { 
      throw std::logic_error("not a UTF-8 string"); 
     } 
     for (size_t j = 0; j < todo; ++j) 
     { 
      if (i == utf8.size()) 
       throw std::logic_error("not a UTF-8 string"); 
      unsigned char ch = utf8[i++]; 
      if (ch < 0x80 || ch > 0xBF) 
       throw std::logic_error("not a UTF-8 string"); 
      uni <<= 6; 
      uni += ch & 0x3F; 
     } 
     if (uni >= 0xD800 && uni <= 0xDFFF) 
      throw std::logic_error("not a UTF-8 string"); 
     if (uni > 0x10FFFF) 
      throw std::logic_error("not a UTF-8 string"); 
     unicode.push_back(uni); 
    } 
    std::wstring utf16; 
    for (size_t i = 0; i < unicode.size(); ++i) 
    { 
     unsigned long uni = unicode[i]; 
     if (uni <= 0xFFFF) 
     { 
      utf16 += (wchar_t)uni; 
     } 
     else 
     { 
      uni -= 0x10000; 
      utf16 += (wchar_t)((uni >> 10) + 0xD800); 
      utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00); 
     } 
    } 
    return utf16; 
} 

答えて

1

std::stringソースが英語またはいくつかのラテン系の言語である場合には(マイルBudnekの答えのように)、その後std::wstringへの変換は、単純なコピーで行うことができます:あなたは、その後LPCWSTRを取るものは何でもAPI関数にc_str()によって返されたポインタを渡すことができます。しかし、一般的に、あなたはあなたが元の文字列を作るために使用されるコードページを知っている必要がMultiByteToWideChar

std::wstring get_utf16(const std::string &str, int codepage) 
{ 
    if (str.empty()) return std::wstring(); 
    int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0); 
    std::wstring res(sz, 0); 
    MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz); 
    return res; 
} 

を使用する必要があります。 GetACP()を使用すると、ユーザーのコンピュータのコードページを見つけることができます。ソース文字列がUTF8の場合は、コードページにCP_UTF8を使用します。

+0

それはUTF8ですが、まだ中国語と正方形を返します – Jose

+0

Uは通常このような文字列を設定します: string url = u8 "/ post/show/933477 /"; いつも失敗する – Jose

+0

修正済み、リクエスト内に「c_str()」を追加するだけで済みました。 – Jose

3

2つの問題があります。

  1. LPCWSTRwchar_tへのポインタであり、std::string::c_str()const char*を返します。これら2つのタイプは異なるため、const char*からLPCWSTRへのキャストは機能しません。
  2. std::basic_string::c_strによって返されたポインタによって指し示されるメモリは、文字列オブジェクトによって所有され、文字列が有効範囲外になると解放されます。

メモリを割り当てて文字列のコピーを作成する必要があります。

新しいワイド文字列にメモリを割り当てる最も簡単な方法は、ちょうどstd::wstringを返すことです。

std::wstring string_to_wstring(const std::string& text) { 
    return std::wstring(text.begin(), text.end()); 
} 
+0

ディレクトリを持つドメイン名を返しますが、やはり中国語と四角形を返します。私はあなたのコードを使用し、c_str()変換を行いました。 https://i.gyazo.com/ea4cd50765bfcbe12c763ea299e7b508.png – Jose

+0

@Miles Budnek:std :: string&str ==>テキストを修正して戻り行(text.begin()...と一致するようにしてください。) –