string s = "おはよう";
wstring ws = FUNCTION(s, ws);
sの内容をwsにどのように割り当てますか?
グーグルを検索し、いくつかのテクニックを使用しましたが、正確なコンテンツを割り当てることができません。コンテンツが歪んでいる。
"おはよう"
システムでエンコードされた文字列を作成する場合、システムのエンコードは何ですか?
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
sの内容をwsにどのように割り当てますか?
グーグルを検索し、いくつかのテクニックを使用しましたが、正確なコンテンツを割り当てることができません。コンテンツが歪んでいる。
"おはよう"
システムでエンコードされた文字列を作成する場合、システムのエンコードは何ですか?
回答:
あなたの例の入力文字列(おはよう)がUTF-8でエンコードされていると想定します(見た目ではそうではありませんが、この説明のためであると想定しましょう:-))Unicode文字列の表現興味があれば、標準ライブラリ(C ++ 11以降)だけで問題を完全に解決できます。
TL; DRバージョン:
#include <locale>
#include <codecvt>
#include <string>
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide_utf16_source_string);
std::wstring wide = converter.from_bytes(narrow_utf8_source_string);
より長いオンラインでコンパイルおよび実行可能な例:
(それらはすべて同じ例を示しています。冗長性のために多くあります...)
注意(古い):
コメントで指摘され、https://stackoverflow.com/a/17106065/6345で説明されているように、標準ライブラリを使用してUTF-8とUTF-16の間で変換すると、異なるプラットフォームでの結果に予期しない違いが生じる場合があります。より良い変換std::codecvt_utf8
については、http://en.cppreference.com/w/cpp/locale/codecvt_utf8で説明されているように考慮してください
注意(新規):
codecvt
ヘッダーはC ++ 17で廃止されたため、この回答で提示された解決策についての懸念が提起されました。ただし、C ++標準委員会はhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.htmlと言って重要な声明を追加しました
このライブラリコンポーネントは、適切な代替品が標準化されるまで、とともに、Annex Dに廃棄する必要があります。
したがって、近い将来、codecvt
この回答のソリューションは安全で移植可能です。
std::codecvt_utf8
初心者向けの例を提供して
<codecvt>
C ++ 17以降は非推奨であることに注意してください。
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
あなたの質問は不充分です。厳密には、その例は構文エラーです。しかし、std::mbstowcs
おそらくあなたが探しているものです。
これはCライブラリ関数であり、バッファで動作しますが、TBohne(旧Mooing Duck)の厚意による、使いやすいイディオムを次に示します。
std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit.
setlocale
コンパイラフラグを調整する必要があるかもしれません。私はWindowsを使用していないのでわかりませんが、これが一般的な機能ではない理由です。可能であれば、他の回答を検討してください。
std::string ws(s.size()); ws.resize(mbstowcs(&ws[0], s.c_str(), s.size());
RAII FTW
Windows APIのみ、誰かがそれを必要とする場合のためのC ++ 11実装前:
#include <stdexcept>
#include <vector>
#include <windows.h>
using std::runtime_error;
using std::string;
using std::vector;
using std::wstring;
wstring utf8toUtf16(const string & str)
{
if (str.empty())
return wstring();
size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0,
str.data(), (int)str.size(), NULL, 0);
if (charsNeeded == 0)
throw runtime_error("Failed converting UTF-8 string to UTF-16");
vector<wchar_t> buffer(charsNeeded);
int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0,
str.data(), (int)str.size(), &buffer[0], buffer.size());
if (charsConverted == 0)
throw runtime_error("Failed converting UTF-8 string to UTF-16");
return wstring(&buffer[0], charsConverted);
}
vector
。文字列の文字を予約してwstring strW(charsNeeded + 1);
、変換用のバッファとして使用します&strW[0]
。最後に、変換して最後のnullが存在することを確認しますstrW[charsNeeded] = 0;
あなたが使用している場合のWindows / Visual Studioの、あなたが使用することができwstringのに文字列を変換する必要が:
#include <AtlBase.h>
#include <atlconv.h>
...
string s = "some string";
CA2W ca2w(s.c_str());
wstring w = ca2w;
printf("%s = %ls", s.c_str(), w.c_str());
wstringをstringに変換する同じ手順(コードページを指定する必要がある場合もあります):
#include <AtlBase.h>
#include <atlconv.h>
...
wstring w = L"some wstring";
CW2A cw2a(w.c_str());
string s = cw2a;
printf("%s = %ls", s.c_str(), w.c_str());
コードページを指定したり、UTF8を指定したりすることもできます(JNI / Javaを操作する場合は、これは非常に便利です)。標準の方法UTF8にはstd :: wstringの変換ははstd ::文字列は、この回答でしたさ。
//
// using ATL
CA2W ca2w(str, CP_UTF8);
//
// or the standard way taken from the answer above
#include <codecvt>
#include <string>
// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.from_bytes(str);
}
// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.to_bytes(str);
}
コードページについて詳しく知りたい場合は、Joel on Software:The Absolute Minimum Every Software Developer Absolutely、Positively Positive Known知るUnicode and Character Setsに関する興味深い記事がありますます。
これらのCA2W(AnsiをWide = unicodeに変換)マクロは、サンプルが含まれているATLおよびMFC文字列変換マクロの一部です。
場合によっては、セキュリティ警告#4995を無効にする必要があります。他の回避策はわかりません(VS2012でWindowsXp用にコンパイルしたときに発生します)。
#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)
編集: まあ、この記事によると、Joelによる記事は「面白い間は、実際の技術的な詳細はかなり軽い」のようです。記事:すべてのプログラマーが、テキストを処理するためのエンコーディングと文字セットについて確実に知っておくべきこと。
char* str = "hello worlddd"; wstring wstr (str, str+strlen(str));
ここ組み合わせへの道だstring
、wstring
との混合文字列定数はwstring
。使用wstringstream
クラスをます。
これはマルチバイト文字エンコーディングでは機能しません。これは、型の安全性を破棄し、std :: stringから7ビット文字をstd:wstringの各文字の下位7ビットに拡張する、おかしな方法です。これは、7ビットのASCII文字列があり、ワイド文字列を必要とするAPIを呼び出す必要がある場合にのみ役立ちます。
#include <sstream>
std::string narrow = "narrow";
std::wstring wide = L"wide";
std::wstringstream cls;
cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
std::wstring total= cls.str();
string
1バイト文字をwstring
格納し、2 バイト文字を格納します。utf8のようなものは、マルチバイト文字を一連の1バイト値として、つまりに格納しstring
ます。文字列クラスはエンコードに役立ちません。私はc ++でクラスをエンコードすることの専門家ではありません。
std::string
をの各文字の下位7ビットに拡張するというおかしな方法ですstd:wstring
。これは、7ビットのASCII文字列があり、ワイド文字列を必要とするAPIを呼び出す必要がある場合にのみ役立ちます。より洗練されたものが必要な場合は、stackoverflow.com / a / 8969776/3258851をご覧ください。
からchar*
へwstring
:
char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));
からstring
へwstring
:
string str = "hello worlddd";
wstring wstr (str.begin(), str.end());
これは、変換される文字列にASCII文字のみが含まれている場合にのみ機能することに注意してください。
atlconv.h
いる場合は、を使用する必要があります。他の回答を確認してください。
それのこの変種は、実際の生活の中で私のお気に入りです。入力が有効な UTF-8の場合、入力をそれぞれのに変換しますwstring
。入力が破損している場合wstring
は、1バイトから構成されます。これは、入力データの品質について本当に確信が持てない場合に非常に役立ちます。
std::wstring convert(const std::string& input)
{
try
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(input);
}
catch(std::range_error& e)
{
size_t length = input.length();
std::wstring result;
result.reserve(length);
for(size_t i = 0; i < length; i++)
{
result.push_back(input[i] & 0xFF);
}
return result;
}
}
QTがあり、関数やものを実装するのに時間がかかる場合は、
std :: string str; QString(str).toStdWString()
QString
、QString
コンストラクタは何らかの理由で文字列を受け入れることができないため、で始める必要があります。
メソッドs2wsはうまく機能します。願っています。
std::wstring s2ws(const std::string& s) {
std::string curLocale = setlocale(LC_ALL, "");
const char* _Source = s.c_str();
size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
std::wstring result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
私自身のテスト(Windows 8、vs2010)に基づいて、mbstowcsは実際に元の文字列を損傷する可能性があり、ANSIコードページでのみ機能します。MultiByteToWideChar / WideCharToMultiByteも文字列の破損を引き起こす可能性がある場合-しかし、知らない文字を「?」で置き換える傾向があります。クエスチョンマークですが、mbstowcsは、不明な文字が検出され、その時点で文字列をカットすると停止する傾向があります。(私はフィンランド語のウィンドウでベトナム文字をテストしました)。
そのため、アナログのansi C関数よりもMulti * -windows api関数を優先してください。
また、あるコードページから別のコードページに文字列をエンコードする最も短い方法は、MultiByteToWideChar / WideCharToMultiByte API関数呼び出しではなく、アナログのATLマクロW2A / A2Wを使用していることです。
したがって、上記のアナログ機能は次のように聞こえます。
wstring utf8toUtf16(const string & str)
{
USES_CONVERSION;
_acp = CP_UTF8;
return A2W( str.c_str() );
}
_acpはUSES_CONVERSIONマクロで宣言されています。
または、古いデータを新しいデータに変換するときによく見落とす機能:
string ansi2utf8( const string& s )
{
USES_CONVERSION;
_acp = CP_ACP;
wchar_t* pw = A2W( s.c_str() );
_acp = CP_UTF8;
return W2A( pw );
}
ただし、これらのマクロはスタックを多用していることに注意してください。W2AまたはA2Wマクロを使用した後は、forループや同じ関数の再帰ループを使用しないでください。
文字列からwstring
std::wstring Str2Wstr(const std::string& str)
{
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
wstringからStringへ
std::string Wstr2Str(const std::wstring& wstr)
{
typedef std::codecvt_utf8<wchar_t> convert_typeX;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.to_bytes(wstr);
}
string s = "おはよう";
エラーです。
wstringを直接使用する必要があります。
wstring ws = L"おはよう";
このコードを使用して、文字列をwstringに変換します
std::wstring string2wString(const std::string& s){
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
int main(){
std::wstring str="your string";
std::wstring wStr=string2wString(str);
return 0;
}
CP_ACP
間違いなく間違いです。突然、実行中のスレッドの環境状態がコードの動作に影響を与えます。お勧めできません。変換で固定文字エンコードを指定します。(エラーの処理を検討してください。)
strings
> 8ビット文字は受け入れないと思います。すでにUTF-8でエンコードされていますか?