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
설명 된대로 고려 하십시오
참고 (신규) :
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
누군가가 필요로하는 경우를 대비하여 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();
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
단일 바이트로 구성됩니다. 입력 데이터의 품질을 실제로 확신 할 수없는 경우 매우 유용합니다.
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
틀림없이 잘못된 주장입니다. 갑자기 실행중인 스레드의 환경 상태는 코드의 동작에 영향을 미칩니다. 바람직하지 않습니다. 변환시 고정 문자 인코딩을 지정하십시오. (그리고 오류 처리를 고려하십시오.)
strings
8 비트 이상의 문자를 허용 하지 않는다고 생각 합니다. 이미 UTF-8로 인코딩되어 있습니까?