cod*_*rog 30 c++ string wchar-t stdstring
我改变了我的类使用std :: string(基于我在这里得到的答案,但是我有一个函数返回wchar_t*.如何将它转换为std :: string?
我试过这个:
std::string test = args.OptionArg();
Run Code Online (Sandbox Code Playgroud)
但它说错误C2440:'初始化':无法从'wchar_t*'转换为'std :: basic_string <_Elem,_Traits,_Ax>'
Ult*_*ior 44
std::wstring ws( args.OptionArg() );
std::string test( ws.begin(), ws.end() );
Run Code Online (Sandbox Code Playgroud)
您可以使用以下函数将宽字符串转换为ASCII字符串:
#include <locale>
#include <sstream>
#include <string>
std::string ToNarrow( const wchar_t *s, char dfault = '?',
const std::locale& loc = std::locale() )
{
std::ostringstream stm;
while( *s != L'\0' ) {
stm << std::use_facet< std::ctype<wchar_t> >( loc ).narrow( *s++, dfault );
}
return stm.str();
}
Run Code Online (Sandbox Code Playgroud)
请注意,这只会替换dfault参数中不存在等效ASCII字符的任何宽字符; 它不会从UTF-16转换为UTF-8.如果要转换为UTF-8,请使用ICU等库.
令人相当失望的是,这个老问题的答案都没有解决将宽字符串转换为 UTF-8 字符串的问题,这在非英语环境中很重要。
\n这是一个可以运行的示例代码,可以用作构造自定义转换器的提示。它基于cppreference.com 中的示例代码中的示例代码。
\n#include <iostream>\n#include <clocale>\n#include <string>\n#include <cstdlib>\n#include <array>\n\nstd::string convert(const std::wstring& wstr)\n{\n const int BUFF_SIZE = 7;\n if (MB_CUR_MAX >= BUFF_SIZE) throw std::invalid_argument("BUFF_SIZE too small");\n std::string result;\n bool shifts = std::wctomb(nullptr, 0); // reset the conversion state\n for (const wchar_t wc : wstr)\n {\n std::array<char, BUFF_SIZE> buffer;\n const int ret = std::wctomb(buffer.data(), wc);\n if (ret < 0) throw std::invalid_argument("inconvertible wide characters in the current locale");\n buffer[ret] = \'\\0\'; // make \'buffer\' contain a C-style string\n result = result + std::string(buffer.data());\n }\n return result;\n}\n\nint main()\n{\n auto loc = std::setlocale(LC_ALL, "en_US.utf8"); // UTF-8\n if (loc == nullptr) throw std::logic_error("failed to set locale");\n std::wstring wstr = L"a\xc4\x85\xc3\x9f\xe6\xb0\xb4-\xe6\x89\xab\xe6\x8f\x8f-\xe2\x82\xac\\u00df\\u6c34\\U0001d10b";\n std::cout << convert(wstr) << "\\n";\n}\n\nRun Code Online (Sandbox Code Playgroud)\n正如预期的那样打印:
\n\nBUFF_SIZE。其中包括 4 作为编码单个字符的 UTF-8 字节的最大数量;2 表示可能的“移位序列”,1 表示尾随\'\\0\'.MB_CUR_MAX是一个运行时变量,所以static_assert在这里不可用char每个宽字符都使用以下方式 转换为其表示形式std::wctomben_US.utf8似乎足够通用(在大多数机器上可用)。在Linux中,可以通过命令在控制台中查询可用的语言环境locale -a。点赞数最高的答案,
\nstd::wstring ws( args.OptionArg() );\nstd::string test( ws.begin(), ws.end() );\nRun Code Online (Sandbox Code Playgroud)\n仅当宽字符表示 ASCII 字符时才能正常工作 - 但这不是宽字符的设计目的。在此解决方案中,转换后的字符串每个源宽字符包含一个字符ws.size() == test.size()。因此,它会丢失原始 wstring 中的信息,并生成无法解释为正确的 UTF-8 序列的字符串。例如,在我的机器上,“\xc4\x84\xc5\x9a\xc4\x86II”的简单转换产生的字符串打印为“ZII”,即使其大小为 5(应该是 8)。
您可以使用wstring并保留Unicode中的所有内容
这是一个老问题,但如果是这样的话,你并不真正寻求转换,而是使用Mircosoft的TCHAR能够构建ASCII和Unicode,你可以回想起std :: string真的
typedef std::basic_string<char> string
Run Code Online (Sandbox Code Playgroud)
所以我们可以定义我们自己的typedef
#include <string>
namespace magic {
typedef std::basic_string<TCHAR> string;
}
Run Code Online (Sandbox Code Playgroud)
然后,你可以使用magic::string同TCHAR,LPCTSTR等
| 归档时间: |
|
| 查看次数: |
51587 次 |
| 最近记录: |