首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将wstring转换为string?

如何将wstring转换为string?
EN

Stack Overflow用户
提问于 2011-01-26 19:58:02
回答 17查看 339K关注 0票数 234

问题是如何将wstring转换为string?

我有下一个例子:

代码语言:javascript
复制
#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;
}

带有注释掉的行的输出是:

代码语言:javascript
复制
std::string =     Hello
std::wstring =    Hello
std::string =     Hello

但没有的只是:

代码语言:javascript
复制
std::wstring =    Hello

示例中有什么错误吗?我可以像上面那样进行转换吗?

编辑

新的例子(考虑到一些答案)是

代码语言:javascript
复制
#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;
}

输出为:

代码语言:javascript
复制
std::string =     Hello
std::wstring =    Hello
std::stringstream =     0x860283c

因此,stringstream不能用于将wstring转换为string。

EN

回答 17

Stack Overflow用户

回答已采纳

发布于 2011-01-26 22:06:16

这是一个基于其他建议的解决方案:

代码语言:javascript
复制
#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上会产生问题。

票数 35
EN

Stack Overflow用户

发布于 2013-08-22 15:57:21

正如Cubbi在其中一条评论中指出的那样,std::wstring_convert (C++11)提供了一个简洁简单的解决方案(您需要#include <locale><codecvt>):

代码语言:javascript
复制
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的评论):

代码语言:javascript
复制
std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some string");

包装器函数可以这样描述:(感谢ArmanSchwarz的评论)

代码语言:javascript
复制
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,则需要将其更改为您正在使用的适当编码:

http://en.cppreference.com/w/cpp/header/codecvt

票数 358
EN

Stack Overflow用户

发布于 2012-08-24 02:18:29

来自:http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html的较旧的解决方案

代码语言:javascript
复制
std::wstring wide( L"Wide" ); 
std::string str( wide.begin(), wide.end() );

// Will print no problemo!
std::cout << str << std::endl;

更新(2021):但是,至少在更新版本的MSVC上,这可能会生成wchar_tchar截断警告。通过在转换函数中使用显式转换,而不是使用std::transform,可以消除警告,例如:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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中的代码点将不起作用。这包括œžŸ,...

票数 144
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4804298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档