string s = "おはよう";
wstring ws = FUNCTION(s, ws);
s의 내용을 ws에 어떻게 할당합니까?
Google을 검색하고 일부 기술을 사용했지만 정확한 콘텐츠를 할당 할 수 없습니다. 내용이 왜곡되었습니다.
"おはよう"시스템 인코딩 문자열을 만드는 시스템 인코딩은 무엇입니까 ?
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
s의 내용을 ws에 어떻게 할당합니까?
Google을 검색하고 일부 기술을 사용했지만 정확한 콘텐츠를 할당 할 수 없습니다. 내용이 왜곡되었습니다.
"おはよう"시스템 인코딩 문자열을 만드는 시스템 인코딩은 무엇입니까 ?
답변:
예제의 입력 문자열 (お は よ う)이 UTF-8로 인코딩되어 있다고 가정하면 (유형에 따라 다르지 않지만이 설명을 위해 있다고 가정합시다 :-)) 유니 코드 문자열 표준 라이브러리 (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 사이를 변환하면 다른 플랫폼에서 결과에 예기치 않은 차이가 발생할 수 있습니다 . 더 나은 변환을 위해서는 http://en.cppreference.com/w/cpp/locale/codecvt_utf8에std::codecvt_utf8 설명 된대로 고려 하십시오
참고 (신규) :
codecvtC ++ 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
누군가가 필요로하는 경우를 대비하여 C ++ 11 이전의 Windows API 전용 :
#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]. 마지막으로 변환 후 마지막 널이 있는지 확인하십시오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을 문자열로 변환하는 동일한 절차 (때로는 codepage 를 지정해야 함 ) :
#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에 표준 : : wstring의 변환은 표준 : : 문자열이 대답했다한다 .
//
// 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의 흥미로운 기사가 있습니다 : 절대적으로 모든 소프트웨어 개발자는 절대적으로 유니 코드와 문자 세트에 대해 반드시 알아야 합니다
이 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();
string1 바이트 문자를 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단일 바이트로 구성됩니다. 입력 데이터의 품질을 실제로 확신 할 수없는 경우 매우 유용합니다.
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, 2010)에서 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 매크로를 사용한 후 동일한 함수에 대해 루프 또는 재귀 루프에 사용하지 마십시오. ASAP를 반환하는 것이 좋습니다. 스택은 일시적인 변환에서 벗어날 수 있습니다.
문자열을 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을 문자열로
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틀림없이 잘못된 주장입니다. 갑자기 실행중인 스레드의 환경 상태는 코드의 동작에 영향을 미칩니다. 바람직하지 않습니다. 변환시 고정 문자 인코딩을 지정하십시오. (그리고 오류 처리를 고려하십시오.)
strings8 비트 이상의 문자를 허용 하지 않는다고 생각 합니다. 이미 UTF-8로 인코딩되어 있습니까?