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

时间:2015-02-25 06:25:41

标签: c++

我的问题是如何在stringstreamwstring

中转换c ++ wstringstream
stringstream fileSearch;
fileSearch<<fileOutput.str();
fileSearch<<"*.jpg";
cout<<fileSearch.str()<<endl;

这是我的代码。我想将此文件搜索字符串流转换为wstring ...可以请一些人用c ++示例代码帮助我... 我想在

中使用这个filesearch stringstream
int numOfFiles(wstring searchPath);

这个功能......

4 个答案:

答案 0 :(得分:5)

std::stringstream始终可以转换为std::string,因此问题会缩小到如何将std::string转换为std::wstring


如果窄字符串编码点是宽字符串编码点的子集,那么您只需复制数据:

const std::string s = ...;
const std::wstring ws( s.begin(), s.end() );

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

在实践中,这意味着这种简单的数据复制方案适用于:

    西方Windows安装中的
  • 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;
}

在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
66 108 229 98 230 114 115 121 108 116 101 116 248 121 46 
Should be 'Blåbærsyltetøy'.
Is '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;
}();

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

H:\dev\explore\_\so\0244>cl iofix.cpp foo.cpp /Feb
iofix.cpp
foo.cpp
Generating Code...

H:\dev\explore\_\so\0244>b
66 108 229 98 230 114 115 121 108 116 101 116 248 121 46
Should be 'Blåbærsyltetøy'.
Is '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>a
66 108 195 165 98 195 166 114 115 121 108 116 101 116 195 184 121 46
Should be 'Blåbærsyltetøy'.
Is 'Blåbærsyltetøy.'.

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

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


1 )在Unix-land中它按原样运行,因为全局C ++语言环境已设置为用户的默认语言环境。

答案 1 :(得分:1)

在C ++ 11中,您也可以使用它将字符串流转换为wstring:

std::wstring stringStream2wstring(std::stringstream& strs)
{
    std::string str = strs.str();
    typedef std::codecvt_utf8<wchar_t> convert_type;
    std::wstring_convert<convert_type, wchar_t> converter;
    return converter.from_bytes(str);
}

注意:该示例使用std :: codecvt_utf8

答案 2 :(得分:0)

一个简短的C ++函数,用于将字符串流转换为wstring:

std::wstring convertToWString(std::stringstream& from)
{
    std::wstring to;
    string stdString = from.str();
    return to.assign(stdString.begin(), stdString.end());
}

注意:此代码仅限于值的ASCII子集

答案 3 :(得分:0)

ValidationAttribute