C++ 문자열(또는 char*)을 wstring(또는 wchar_t*)으로 변환합니다.
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
제가 어떻게 스토브의 내용물을 할당할 수 있습니까?
구글을 검색하고 몇 가지 기술을 사용했지만 정확한 콘텐츠를 할당할 수 없습니다.내용이 왜곡되었습니다.
예제의 입력 문자열이 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 사이를 변환하는 경우 다른 플랫폼에서 결과에 예상치 못한 차이가 발생할 수 있습니다.더 나은 변환을 위해 고려합니다.std::codecvt_utf8http://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 에 다음과 같은 중요한 성명을 추가했습니다.
이 라이브러리 구성요소는 적절한 교체가 표준화될 때까지 부속문서 D에 따라 폐기되어야 합니다.
그래서 가까운 미래에,codecvt이 답변의 솔루션은 안전하고 휴대할 수 있습니다.
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
질문이 제대로 지정되지 않았습니다.엄밀히 말하면, 그 예는 구문 오류입니다.하지만, 그것은 아마도 당신이 찾고 있는 것일 것입니다.
C 라이브러리 기능이며 버퍼에서 작동하지만, 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.
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로 작업할 때 매우 유용함).std::wstring을 utf8 std::string으로 변환하는 표준 방법이 이 답변에 나와 있습니다.
//
// 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에 대한 흥미로운 기사가 있습니다.절대 최소 모든 소프트웨어 개발자는 유니코드 및 문자 집합에 대해 절대적, 긍정적으로 알아야 합니다.
이러한 CA2W(Convert Ansi to Wide=module) 매크로는 ATL 및 MFC String Conversion 매크로의 일부이며 샘플이 포함되어 있습니다.
때때로 보안 경고 #4995'를 사용하지 않도록 설정해야 합니다. 다른 해결 방법은 모르겠습니다(VS2012에서 Windows XP용으로 컴파일할 때 발생합니다).
#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)
편집: 자, 이 기사에 따르면 조엘의 기사는 "흥미를 주는 동안 실제 기술적 세부 사항에 대해 매우 가볍습니다."라고 합니다.기사:모든 프로그래머가 텍스트 작업을 위해 인코딩 및 문자 집합에 대해 절대적으로 알아야 할 사항.
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);
}
결합하는 방법은 다음과 같습니다.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();
char*wstring:
char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));
stringwstring:
string str = "hello worlddd";
wstring wstr (str.begin(), str.end());
변환 중인 문자열에 ASCII 문자만 포함된 경우에만 이 기능이 제대로 작동합니다.
이것의 변형은 내가 실생활에서 가장 좋아하는 것입니다.유효한 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;
}
}
Boost를 사용합니다.로케일:
ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
부스트 경로 또는 표준 경로를 사용할 수 있으며, 이는 훨씬 더 쉽습니다.크로스 플랫폼 애플리케이션의 경우 향상 경로가 더 쉽습니다.
#include <boost/filesystem/path.hpp>
namespace fs = boost::filesystem;
//s to w
std::string s = "xxx";
auto w = fs::path(s).wstring();
//w to s
std::wstring w = L"xxx";
auto s = fs::path(w).string();
std를 사용하려는 경우:
#include <filesystem>
namespace fs = std::filesystem;
//The same
c++ 이전 버전
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
//The same
내부의 코드는 세부 사항을 풀 필요가 없는 변환기를 여전히 구현합니다.
큰 오버헤드가 없는 가장 단순한 옵션은 다음과 같습니다.
포함:
#include <atlbase.h>
#include <atlconv.h>
변환:
char* whatever = "test1234";
std::wstring lwhatever = std::wstring(CA2W(std::string(whatever).c_str()));
필요한 경우:
lwhatever.c_str();
문자열 towstring
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 to 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);
}
당신이 QT를 가지고 있고 당신이 사용할 수 있는 기능과 것들을 구현하기가 귀찮다면.
std::string str;
QString(str).toStdWString()
여기 모든 사람에게 효과가 없을 수도 있는 저의 가장 기본적인 해결책이 있습니다.하지만 많은 사람들에게 효과가 있을 것입니다.
가이드라인 지원 라이브러리를 사용해야 합니다.많은 C++ 위원회 저자들이 설계한 꽤 공식적인 C++ 라이브러리입니다.
std::string to_string(std::wstring const & wStr)
{
std::string temp = {};
for (wchar_t const & wCh : wStr)
{
// If the string can't be converted gsl::narrow will throw
temp.push_back(gsl::narrow<char>(wCh));
}
return temp;
}
제 기능은 가능하면 변환을 허용하는 것뿐입니다.그렇지 않으면 예외를 설정합니다.
gsl::sl을 사용하여 (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es49-if-you-must-use-a-cast-use-a-named-cast) .
방법 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;
}
자체 테스트(윈도우즈 8, vs 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 매크로를 사용한 후 동일한 기능에 대한 루프 또는 재귀 루프에 사용하지 마십시오. 따라서 스택은 일시적인 변환으로부터 자유로워집니다.
std::string -> wchar_t[]안전하게mbstowcs_s함수:
auto ws = std::make_unique<wchar_t[]>(s.size() + 1);
mbstowcs_s(nullptr, ws.get(), s.size() + 1, s.c_str(), s.size());
이것은 나의 샘플 코드입니다.
이 코드를 사용하여 문자열을 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;
}
string s = "おはよう";오류입니다.
wstring을 직접 사용해야 합니다.
wstring ws = L"おはよう";
언급URL : https://stackoverflow.com/questions/2573834/c-convert-string-or-char-to-wstring-or-wchar-t
'programing' 카테고리의 다른 글
| Entity 프레임워크를 통해 Oracle 데이터베이스에 대한 ID를 자동으로 생성하는 방법은 무엇입니까? (0) | 2023.08.02 |
|---|---|
| 모든 플라스크 경로에 접두사 추가 (0) | 2023.08.02 |
| 특수 문자가 포함된 Mysql 명령줄 암호가 작동하지 않습니다. (0) | 2023.07.28 |
| Oracle SQL 쿼리를 사용하여 그룹의 각 요소에 대한 시퀀스 번호 추가 (0) | 2023.07.28 |
| 함수를 반환하는 함수를 만들려면 어떻게 해야 합니까? (0) | 2023.07.28 |