Rap*_*tor 11 c++ windows unicode stl wofstream
我目前正在编写一个应用程序,它要求我在任意窗口上调用GetWindowText并将该数据存储到文件中以供以后处理.长话短说,我注意到我的工具在"战地3"中失败了,我将问题缩小到其窗口标题中的以下字符:http: //www.fileformat.info/info/unicode/char/2122/index. HTM
所以我创建了一个小测试应用程序,它只执行以下操作:
std::wcout << L"\u2122";
Run Code Online (Sandbox Code Playgroud)
低并且看到在程序的其余部分中断输出到控制台窗口.
当MessageBoxW等API显示它时,为什么MSVC STL会阻塞这个角色(我假设其他人)?
如何将这些字符打印到我的文件中?
在Windows 7 x64下测试VC10和VC11.
抱歉这个构造不好的帖子,我在这里撕扯我的头发.
谢谢.
编辑:
最小的测试用例
#include <fstream>
#include <iostream>
int main()
{
{
std::wofstream test_file("test.txt");
test_file << L"\u2122";
}
std::wcout << L"\u2122";
}
Run Code Online (Sandbox Code Playgroud)
预期结果:'™'字符打印到控制台和文件.观察结果:文件已创建但为空.没有输出到控制台.
我已经确认我用于我的控制台的字体能够显示有问题的字符,并且该文件肯定是空的(大小为0字节).
编辑:
进一步的调试表明,在流中设置了'failbit'和'badbit'.
编辑:
我也尝试过使用Boost.Locale,即使全新的语言环境充满了所有标准流,我也遇到了同样的问题.
Ber*_*rtR 14
要写入文件,您必须正确设置区域设置,例如,如果要将它们写为UTF-8字符,则必须添加
const std::locale utf8_locale
= std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
test_file.imbue(utf8_locale);
Run Code Online (Sandbox Code Playgroud)
您必须添加这两个包含文件
#include <codecvt>
#include <locale>
Run Code Online (Sandbox Code Playgroud)
要写入控制台,您必须通过添加将控制台设置为正确的模式(这是特定于Windows的)
_setmode(_fileno(stdout), _O_U8TEXT);
Run Code Online (Sandbox Code Playgroud)
(如果你想使用UTF-8).
为此,您必须添加这两个包含文件:
#include <fcntl.h>
#include <io.h>
Run Code Online (Sandbox Code Playgroud)
此外,您必须确保使用支持Unicode的字体(例如Lucida Console).您可以在控制台窗口的属性中更改字体.
完整的程序现在看起来像这样:
#include <fstream>
#include <iostream>
#include <codecvt>
#include <locale>
#include <fcntl.h>
#include <io.h>
int main()
{
const std::locale utf8_locale = std::locale(std::locale(),
new std::codecvt_utf8<wchar_t>());
{
std::wofstream test_file("c:\\temp\\test.txt");
test_file.imbue(utf8_locale);
test_file << L"\u2122";
}
_setmode(_fileno(stdout), _O_U8TEXT);
std::wcout << L"\u2122";
}
Run Code Online (Sandbox Code Playgroud)