C++ C++;将字符串(或字符*)转换为wstring(或wchar\u t*)
如何将s的内容分配给wsC++ C++;将字符串(或字符*)转换为wstring(或wchar\u t*),c++,string,wstring,C++,String,Wstring,如何将s的内容分配给ws 搜索谷歌并使用了一些技术,但他们无法指定确切的内容。内容失真。您的问题没有明确说明。严格来说,该示例是一个语法错误。然而,这可能就是你想要的 这是一个C库函数,在缓冲区上运行,但这里有一个易于使用的习惯用法,由Mooing Duck提供: string s = "おはよう"; wstring ws = FUNCTION(s, ws); string s=”おはよう";是一个错误 您应该直接使用wstring: std::wstring ws(s.size(), L'
搜索谷歌并使用了一些技术,但他们无法指定确切的内容。内容失真。您的问题没有明确说明。严格来说,该示例是一个语法错误。然而,这可能就是你想要的 这是一个C库函数,在缓冲区上运行,但这里有一个易于使用的习惯用法,由Mooing Duck提供:
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
string s=”おはよう";代码>是一个错误
您应该直接使用wstring:
std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(::mbstowcs_s(&ws[0], ws.size(), s.c_str(), s.size())); // Shrink to fit.
从char*
到wstring
:
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));
从string
到wstring
:
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
char* str = "hello worlddd";
wstring wstr (str, str+strlen(str));
请注意,只有当转换的字符串仅包含ASCII字符时,此方法才有效。方法s2ws效果良好。希望有所帮助
string str = "hello worlddd";
wstring wstr (str.begin(), str.end());
假设示例中的输入字符串(おはよう) 是您感兴趣的Unicode字符串的UTF-8编码(从外观上看,它不是,但为了这个解释,我们假设它是:-)表示,那么您的问题可以完全通过标准库(C++11和更新版本)解决
<>>太长了,读不下去了:
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;
}
#包括
#包括
#包括
std::wstring_转换器;
std::string slown=转换器到字节(宽utf16\U源\U字符串);
std::wstring wide=converter.from_字节(窄\u utf8\u源\u字符串);
更长的在线可编译和可运行示例:
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;
}
(它们都显示了相同的示例。只是有许多用于冗余…)
注释(旧):
在注释和解释中指出,当使用标准库在UTF-8和UTF-16之间转换时,可能会导致不同平台上的结果出现意想不到的差异。为了更好地转换,请考虑<代码> STD::CODECDVTUTF88/COD>(如
所述)。
注意(新):
<>代码> CODECVT 头在C++ 17中被弃用,对该答案中出现的解提出了一些担忧,但是C++标准委员会在中增加了一个重要的声明。
该库部件应按照附录D的规定报废,直至适当的更换件标准化
因此,在可预见的未来,此答案中的codevt
解决方案是安全的、可移植的。如果您使用的是Windows/Visual Studio,并且需要将字符串转换为wstring,您可以使用:
#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);
#包括
//
//使用ATL
CA2W-CA2W(str,CP_-UTF8);
//
//或者从上面的答案中选择标准方法
#包括
#包括
//将UTF-8字符串转换为wstring
std::wstring utf8_到_wstring(const std::string和str){
std::wstring_conv;
从字节(str)返回myconv;
}
//将wstring转换为UTF-8字符串
std::string wstring_to_utf8(const std::wstring&str){
std::wstring_conv;
返回myconv.to_字节(str);
}
如果您想了解更多关于代码页的信息,有一篇关于Joel on Software的有趣文章:
这些CA2W(将Ansi转换为宽=unicode)宏是的一部分,包括示例
有时您需要禁用安全警告#4995',我不知道还有其他解决方法(对我来说,这是在VS2012中为WindowsXp编译时发生的)
#pragma警告(推送)
#杂注警告(禁用:4995)
#包括Joel的文章似乎是:“虽然很有趣,但它对实际技术细节的了解非常清楚”。文章:。仅限Windows API,在C++11实现之前,以防有人需要它:
#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)
#包括
#包括
#包括
使用std::runtime\u错误;
使用std::string;
使用std::vector;
使用std::wstring;
wstring utf8toUtf16(常量字符串和字符串)
{
if(str.empty())
返回wstring();
size\u t charsNeeded=::多字节teToWideChar(CP\u UTF8,0,
str.data(),(int)str.size(),NULL,0);
if(charsNeed==0)
抛出运行时_错误(“将UTF-8字符串转换为UTF-16失败”);
向量缓冲区(CharsNeed);
int charsConverted=::MultiByteToWideChar(CP_UTF8,0,
str.data(),(int)str.size(),&buffer[0],buffer.size();
如果(字符转换==0)
抛出运行时_错误(“将UTF-8字符串转换为UTF-16失败”);
返回wstring(缓冲区[0],字符转换);
}
使用此代码将字符串转换为wstring
#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);
}
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;
}
}
这里有一种将string
、wstring
和混合字符串常量组合到wstring
的方法。使用wstringstream
类
这不适用于多字节字符编码。这只是一种放弃类型安全性并将7位字符从std::string扩展到std:wstring每个字符的低7位的愚蠢方式。这仅在您有7位ASCII字符串并且需要调用需要宽字符串的API时才有用
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;
}
#包括
std::string shown=“窄”;
std::wstring wide=L“宽”;
std::wstringstream cls;
cls使用Boost.Locale:
#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();
ws=boost::locale::conv::utf到utf;
基于我自己的测试(在windows 8、vs2010上)mbstowcs实际上会损坏原始字符串,它只适用于ANSI代码页。如果MultiByteToWideChar/WideCharToMultiByte也会导致字符串损坏-但它们倾向于用“?”问号替换它们不知道的字符,但mbstowcs在遇到未知字符并在该点剪切字符串时往往会停止。(我在芬兰的窗户上测试过越南语字符)
因此,与模拟ANSIC函数相比,更喜欢使用Multi*-windows api函数
我还注意到,将字符串从一个代码页编码到另一个代码页的最短方法不是使用multibytetowidechart/widechart多字节api函数调用,而是它们的模拟ATL宏:W2A/A2W
因此,上述模拟功能听起来像:
ws = boost::locale::conv::utf_to_utf<wchar_t>(s);
_acp在USES\U转换宏中声明
或者,在执行旧数据到新数据的转换时,我经常错过的功能:
wstring utf8toUtf16(const string & str)
{
USES_CONVERSION;
_acp = CP_UTF8;
return A2W( str.c_str() );
}
string ansi2utf8( const string& s )
{
USES_CONVERSION;
_acp = CP_ACP;
wchar_t* pw = A2W( s.c_str() );
_acp = CP_UTF8;
return W2A( pw );
}
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;
}
}
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;
}
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);
}
std::string str;
QString(str).toStdWString()
auto ws = std::make_unique<wchar_t[]>(s.size() + 1);
mbstowcs_s(nullptr, ws.get(), s.size() + 1, s.c_str(), s.size());
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;
}
#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();
#include <filesystem>
namespace fs = std::filesystem;
//The same
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
//The same