如何将std :: stringstream转换为std :: wstring

Eng*_*ngr 2 c++

我的问题是如何stringstreamwstringwstringstream

stringstream fileSearch;
fileSearch<<fileOutput.str();
fileSearch<<"*.jpg";
cout<<fileSearch.str()<<endl;
Run Code Online (Sandbox Code Playgroud)

这是我的代码。我想将这个fileSearch字符串流转换成wstring ...有人可以帮我请c ++示例代码...我想在

int numOfFiles(wstring searchPath);
Run Code Online (Sandbox Code Playgroud)

这个功能...

Che*_*Alf 5

std::stringstream总是可以转化为std::string,所以问题简化为如何转换std::stringstd::wstring


如果窄字符串编码点是宽字符串编码点的子集,则可以简单地将数据复制到:

const std::string s = ...;
const std::wstring ws( s.begin(), s.end() );
Run Code Online (Sandbox Code Playgroud)

当宽字符串是UTF-16或UTF-32编码时,这适用于原始ASCII及其扩展名Latin-1。

实际上,这意味着该简单的数据复制方案适用于:

  • Windows 1的西方安装中的Latin-1,因为Latin-1是Windows ANSI Western的子集。

  • 在其他Windows安装环境和Unix-land中,ASCII是因为默认的系统窄编码(通常)不是Latin-1的扩展。


当窄字符串编码点不是宽字符串编码点的子集时,必须采用一些更有效的转换。

std::string的编码是语言环境的窄文本编码且不包含嵌入式零字节时,以下代码适用:

#include <iostream>
#include <locale>       // std::locale
#include <locale.h>     // setlocale
#include <stdexcept>    // std::runtime_error
#include <stdlib.h>     // mbstowcs
#include <string>
using namespace std;

auto hopefully( const bool condition ) -> bool { return condition; }
auto fail( const string& message ) -> bool { throw runtime_error( message ); }

auto widened( const string& s, locale const& loc = locale() )
    -> wstring
{
    const int n = s.length();
    if( n == 0 ) { return L""; }

    const int max_wide_encoding_values = (sizeof( wchar_t ) == 2? 2 : 1);
    wstring ws( max_wide_encoding_values*s.length(), L'\0' );

    const auto n_characters_stored = mbstowcs( &ws[0], &s[0], ws.size() );
    hopefully( n_characters_stored != -1 )
        || fail( "mbstowcs failed" );
    ws.resize( n_characters_stored );
    return ws;
}

auto operator<<( wostream& stream, const string& s )
    -> wostream&
{ return stream << s.c_str(); }

auto main() -> int
{
    setlocale( LC_ALL, "" );
    locale::global( locale( "" ) );

    const wstring ws = widened( "Blåbærsyltetøy." );
    for( const wchar_t wc : ws )
    {
        wcout << int( wc ) << ' ';
    }
    wcout << endl;
    wcout << L"Should be 'Blåbærsyltetøy'." << endl;
    wcout << L"Is '" << ws << L"'." << endl;
}
Run Code Online (Sandbox Code Playgroud)

在Ubuntu(在Windows的VirtualBox中)中,输出正常:

alf @ devubuntu32:〜/ host / dev / explore / _ / so / 0244 $ g ++ foo.cpp -std = c ++ 11 
alf @ devubuntu32:〜/ host / dev / explore / _ / so / 0244 $ ./a .out
6610822998230114115121108116101116248121 46 
应该是“Blåbærsyltetøy”。
是“Blåbærsyltetøy”。
alf @ devubuntu32:〜/ host / dev / explore / _ / so / 0244 $?

在Windows中,它是1,必须加入一些修正,使宽流输出工作:

#include <io.h>
#include <fcntl.h>
#include <stdio.h>

static const bool _ = []() -> bool
{
    const int fd = _fileno( stdout );
    _setmode( fd, _isatty( fd )? _O_WTEXT : _O_U8TEXT );
    return true;
}();
Run Code Online (Sandbox Code Playgroud)

然后在Windows中使用Visual C ++,输出为

H:\ dev \ explore \ _ \ so \ 0244> cl iofix.cpp foo.cpp / Feb
iofix.cpp
foo.cpp
产生程式码...

H:\ dev \ explore \ _ \ so \ 0244> b
6610822998230114115121108116101116248121 46
应该是“Blåbærsyltetøy”。
是“Blåbærsyltetøy”。

H:\ dev \ explore \ _ \ so \ 0244> _

但是,在Windows中使用MinGW g ++时,默认输出不正确:

H:\ dev \ explore \ _ \ so \ 0244> g ++ iofix.cpp foo.cpp

H:\ dev \ explore \ _ \ so \ 0244> 一个
66 108 195 165 98 195 166 114 115 121 108 116 101 116 195 184 121 46
应该是“Blåbærsyltetøy”。
是“BlÃ¥bærsyltetøy”。

H:\ dev \ explore \ _ \ so \ 0244> _

原因是默认的g ++ C ++执行字符集为UTF-8,这不是Windows中默认用户的语言环境指定的窄文本编码。一个简单的解决方法是将正确的执行字符集指定为g ++。但是,实际上只有支持这些选项的g ++发行版才有可能,例如Nuwen发行版不支持。


1)在Unix领域中按原样工作,因为全局C ++语言环境已设置为用户的默认语言环境。