如何将std :: wstring写入文件?

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)

  • 如果字符串实际上包含非 8 位字符,这在 Windows 中不起作用 (2认同)

Jer*_*fin 14

std::wstring用于UTF-16或UTF-32,而不是 UTF-8.对于UTF-8,您可能只想使用std::string并写出来std::cout.只是FWIW,C++ 0x将具有Unicode文字,这应该有助于澄清这样的情况.

  • @oystein:Jerry告诉你的是(1)如果源代码是UTF-8编码,`wstring`不会给你UTF-8编码,而(2)`string`会这样做.干杯&hth., (3认同)
  • @oystein:wchar_t不能(合理地)代表UTF-8 - 它的整个*raison d'être*代表宽字符而不是多字节编码. (3认同)
  • @oystein:是的,但UTF-8的重点是将代码点编码为8位"块".`wchar_t`专门用于处理大于8位的"块".因此,虽然你可以*将UTF-8存储到`wchar_t`中,但这样做完全没有意义.`char`保证是(至少)8位,这反过来保证它将保持UTF-8数据没有问题. (3认同)
  • 不,wstring只是一个basic_string <wchar_t>.而已. (2认同)

sci*_*gor 7

为什么不把文件写成二进制文件.只需在std :: ios :: binary设置中使用ofstream即可.编辑应该能够解释它.不要忘记开头的Unicode标志0xFEFF.你最好用图书馆写作,试试其中一个:

http://www.codeproject.com/KB/files/EZUTF.aspx

http://www.gnu.org/software/libiconv/

http://utfcpp.sourceforge.net/


Ste*_*end 5

这里有一个(Windows 特定的)解决方案应该适合您。基本上,转换wstring为 UTF-8 代码页,然后使用ofstream.

\n\n
#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}\n
Run Code Online (Sandbox Code Playgroud)\n


Bas*_*evs 5

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”。