Oys*_*ein 18 c++ unicode file wstring wofstream
我有一个wstring声明如此:
// random wstring
std::wstring str = L"abcàdëefŸg€hhhhhhhµa";
Run Code Online (Sandbox Code Playgroud)
文字将是UTF-8编码,因为我的源文件是.
[编辑:根据Mark Ransom,情况不一定如此,编译器将决定使用什么编码 - 让我们假设我从例如UTF-8编码的文件中读取此字符串]
我非常希望将其转换为文件读取(当文本编辑器设置为正确的编码时)
abcàdëefŸg€hhhhhhhµa
Run Code Online (Sandbox Code Playgroud)
但是ofstream不是很合作(拒绝接受wstring参数),并且wofstream据说需要知道语言环境和编码设置.我只想输出这组字节.通常如何做到这一点?
编辑:它必须是跨平台的,不应该依赖于UTF-8编码.我碰巧有一组存储在a中的字节wstring,并希望输出它们.它很可能是UTF-16或纯ASCII.
ST3*_*ST3 32
为了std::wstring你需要std::wofstream
std::wofstream f(L"C:\\some file.txt");
f << str;
f.close();
Run Code Online (Sandbox Code Playgroud)
Jer*_*fin 14
std::wstring用于UTF-16或UTF-32,而不是 UTF-8.对于UTF-8,您可能只想使用std::string并写出来std::cout.只是FWIW,C++ 0x将具有Unicode文字,这应该有助于澄清这样的情况.
为什么不把文件写成二进制文件.只需在std :: ios :: binary设置中使用ofstream即可.编辑应该能够解释它.不要忘记开头的Unicode标志0xFEFF.你最好用图书馆写作,试试其中一个:
http://www.codeproject.com/KB/files/EZUTF.aspx
http://www.gnu.org/software/libiconv/
http://utfcpp.sourceforge.net/
这里有一个(Windows 特定的)解决方案应该适合您。基本上,转换wstring为 UTF-8 代码页,然后使用ofstream.
#include < windows.h >\n\nstd::string to_utf8(const wchar_t* buffer, int len)\n{\n int nChars = ::WideCharToMultiByte(\n CP_UTF8,\n 0,\n buffer,\n len,\n NULL,\n 0,\n NULL,\n NULL);\n if (nChars == 0) return "";\n\n string newbuffer;\n newbuffer.resize(nChars) ;\n ::WideCharToMultiByte(\n CP_UTF8,\n 0,\n buffer,\n len,\n const_cast< char* >(newbuffer.c_str()),\n nChars,\n NULL,\n NULL); \n\n return newbuffer;\n}\n\nstd::string to_utf8(const std::wstring& str)\n{\n return to_utf8(str.c_str(), (int)str.size());\n}\n\nint main()\n{\n std::ofstream testFile;\n\n testFile.open("demo.xml", std::ios::out | std::ios::binary); \n\n std::wstring text =\n L"< ?xml version=\\"1.0\\" encoding=\\"UTF-8\\"? >\\n"\n L"< root description=\\"this is a na\xc3\xafve example\\" >\\n< /root >";\n\n std::string outtext = to_utf8(text);\n\n testFile << outtext;\n\n testFile.close();\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n
C++ 具有在输出或文件写入时执行从宽字符到本地化字符的转换的方法。为此目的使用codecvt facet。
您可以使用标准std::codecvt_byname或非标准 codecvt_facet implementation。
#include <locale>
using namespace std;
typedef codecvt_facet<wchar_t, char, mbstate_t> Cvt;
locale utf8locale(locale(), new codecvt_byname<wchar_t, char, mbstate_t> ("en_US.UTF-8"));
wcout.imbue(utf8locale);
wcout << L"Hello, wide to multybyte world!" << endl;
Run Code Online (Sandbox Code Playgroud)
请注意,在某些平台上 codecvt_byname 只能为系统中安装的语言环境发出转换。因此,我建议在 stackoverflow 中搜索“utf8 codecvt”,并从列出的自定义 codecvt 实现的许多参考文献中进行选择。
编辑:由于 OP 声明字符串已经编码,他应该做的就是从他的代码的每个标记中删除前缀 L 和“w”。