问题是如何将wstring转换为string?
我有下一个例子:
#include <string>
#include <iostream>
int main()
{
std::wstring ws = L"Hello";
std::string s( ws.begin(), ws.end() );
//std::cout <<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::cout <<"std::string = "<<s<<std::endl;
}
带有注释掉的行的输出是:
std::string = Hello
std::wstring = Hello
std::string = Hello
但没有的只是:
std::wstring = Hello
示例中有什么错误吗?我可以像上面那样进行转换吗?
编辑
新的例子(考虑到一些答案)是
#include <string>
#include <iostream>
#include <sstream>
#include <locale>
int main()
{
setlocale(LC_CTYPE, "");
const std::wstring ws = L"Hello";
const std::string s( ws.begin(), ws.end() );
std::cout<<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::stringstream ss;
ss << ws.c_str();
std::cout<<"std::stringstream = "<<ss.str()<<std::endl;
}
输出为:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
因此,stringstream不能用于将wstring转换为string。
发布于 2011-01-26 22:06:16
这是一个基于其他建议的解决方案:
#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>
int main() {
std::setlocale(LC_ALL, "");
const std::wstring ws = L"ħëłlö";
const std::locale locale("");
typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
const converter_type& converter = std::use_facet<converter_type>(locale);
std::vector<char> to(ws.length() * converter.max_length());
std::mbstate_t state;
const wchar_t* from_next;
char* to_next;
const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
if (result == converter_type::ok or result == converter_type::noconv) {
const std::string s(&to[0], to_next);
std::cout <<"std::string = "<<s<<std::endl;
}
}
这通常适用于Linux,但在Windows上会产生问题。
发布于 2013-08-22 15:57:21
正如Cubbi在其中一条评论中指出的那样,std::wstring_convert
(C++11)提供了一个简洁简单的解决方案(您需要#include
<locale>
和<codecvt>
):
std::wstring string_to_convert;
//setup converter
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( string_to_convert );
在遇到这个问题之前,我使用的是wcstombs
和繁琐的内存分配/释放的组合。
http://en.cppreference.com/w/cpp/locale/wstring_convert
update(2013.11.28)
One liners可以这样描述(感谢Guss的评论):
std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some string");
包装器函数可以这样描述:(感谢ArmanSchwarz的评论)
std::wstring s2ws(const std::string& str)
{
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.from_bytes(str);
}
std::string ws2s(const std::wstring& wstr)
{
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.to_bytes(wstr);
}
注意:对于string
/wstring
应该作为引用传递给函数还是作为文字传递给函数(由于C++11和编译器更新),还存在一些争议。我将把决定留给实现的人,但这是值得知道的。
注意:我在上面的代码中使用了std::codecvt_utf8
,但是如果您没有使用UTF-8,则需要将其更改为您正在使用的适当编码:
发布于 2012-08-24 02:18:29
来自:http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html的较旧的解决方案
std::wstring wide( L"Wide" );
std::string str( wide.begin(), wide.end() );
// Will print no problemo!
std::cout << str << std::endl;
更新(2021):但是,至少在更新版本的MSVC上,这可能会生成wchar_t
到char
截断警告。通过在转换函数中使用显式转换,而不是使用std::transform
,可以消除警告,例如:
std::wstring wide( L"Wide" );
std::string str;
std::transform(wide.begin(), wide.end(), std::back_inserter(str), [] (wchar_t c) {
return (char)c;
});
或者如果您不喜欢预分配而不使用back_inserter
std::string str(wide.length(), 0);
std::transform(wide.begin(), wide.end(), str.begin(), [] (wchar_t c) {
return (char)c;
});
参见各种编译器上的示例here。
注意,这里根本没有进行字符集转换。这样做只是将每个迭代的wchar_t
分配给一个char
--一个截断转换。它使用std::string c'tor
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
如评论中所述:
在几乎每种编码中,
值0-127都是相同的,因此截断所有小于127的值将产生相同的文本。输入一个中文字符,您就会看到失败。
windows代码页1252 (默认的Windows英语)的值128-255与unicode的值128-255基本相同,所以如果这就是您正在使用的代码页,那么这些字符中的大多数都应该被截断为正确的值。(我完全期望á和ó能够工作,我知道我们的代码依赖于这一点,我很快就会修复它)
请注意,Win1252中范围0x80 - 0x9F
中的代码点将不起作用。这包括€
,œ
,ž
,Ÿ
,...
https://stackoverflow.com/questions/4804298
复制相似问题