Windows Unicode C ++流输出失败 [英] Windows Unicode C++ Stream Output Failure
问题描述
我目前正在写一个应用程序,它要求我在任意窗口上调用GetWindowText,并将该数据存储到一个文件以供以后处理。长话短说,我注意到我的工具在战地3上失败了,我把问题缩小到窗口标题中的以下字符:
http://www.fileformat.info/info/unicode/char/2122/index.htm
所以我创建了一个测试应用程序,只是做以下:
std :: wcout< < L\\\™;
低,并注意在程序的其余部分中断到控制台窗口的输出。
为什么当MessageBoxW等API显示它的时候,MSVC STL会阻塞这个字符(我假设其他人)?
在Windows 7 x64下在VC10和VC11上测试。
对于建构不佳的邮件,我在这里撕毁了头发。
谢谢。
EDIT:
最小测试用例
#include< fstream> ;
#include< iostream>
int main()
{
{
std :: wofstream test_file(test.txt);
test_file<< L\\\™;
}
std :: wcout<< L\\\™;
}
预期结果:'TM'字符打印到控制台和文件。
观察到的结果:文件已创建,但为空。没有输出到控制台。
我已经确认我的控制台使用的字体能够显示有问题的字符,并且文件肯定是空的字节大小)。
编辑:
进一步的调试表明'failbit'和'badbit'
我也尝试过使用Boost.Locale和I
要写入一个文件,您必须正确设置语言环境,例如,如果要将其写为UTF-8字符,则必须添加
const std :: locale utf8_locale
= std :: locale(std :: locale(),new std :: codecvt_utf8< wchar_t>());
test_file.imbue(utf8_locale);
您必须添加这两个包含文件
#include< codecvt>
#include< locale>
要写入控制台,必须将控制台设置为正确的模式添加
_setmode(_fileno(stdout),_O_U8TEXT);
(如果您要使用UTF-8)。
为此,你必须添加这两个包含文件:
#include< fcntl.h>
#include< io.h>
此外,您必须确保您使用的是支持Unicode的字体安慰)。您可以在控制台窗口的属性中更改字体。
完整的程序现在如下所示:
#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\\\™;
}
_setmode(_fileno(stdout),_O_U8TEXT);
std :: wcout<< L\\\™;
}
I am currently writing an application which requires me to call GetWindowText on arbitrary windows and store that data to a file for later processing. Long story short, I noticed that my tool was failing on Battlefield 3, and I narrowed the problem down to the following character in its window title: http://www.fileformat.info/info/unicode/char/2122/index.htm
So I created a little test app which just does the following:
std::wcout << L"\u2122";
Low and behold that breaks output to the console window for the remainder of the program.
Why is the MSVC STL choking on this character (and I assume others) when APIs like MessageBoxW etc display it just fine?
How can I get those characters printed to my file?
Tested on both VC10 and VC11 under Windows 7 x64.
Sorry for the poorly constructed post, I'm tearing my hair out here.
Thanks.
EDIT:
Minimal test case
#include <fstream>
#include <iostream>
int main()
{
{
std::wofstream test_file("test.txt");
test_file << L"\u2122";
}
std::wcout << L"\u2122";
}
Expected result: '™' character printed to console and file. Observed result: File is created but is empty. No output to console.
I have confirmed that the font I"m using for my console is capable of displaying the character in question, and the file is definitely empty (0 bytes in size).
EDIT:
Further debugging shows that the 'failbit' and 'badbit' are set in the stream(s).
EDIT:
I have also tried using Boost.Locale and I am having the same issue even with the new locale imbued globally and explicitly to all standard streams.
To write into a file, you have to set the locale correctly, for example if you want to write them as UTF-8 characters, you have to add
const std::locale utf8_locale
= std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
test_file.imbue(utf8_locale);
You have to add these 2 include files
#include <codecvt>
#include <locale>
To write to the console you have to set the console in the correct mode (this is windows specific) by adding
_setmode(_fileno(stdout), _O_U8TEXT);
(in case you want to use UTF-8).
For this you have to add these 2 include files:
#include <fcntl.h>
#include <io.h>
Furthermore you have to make sure that your are using a font that supports Unicode (such as for example Lucida Console). You can change the font in the properties of your console window.
The complete program now looks like this:
#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";
}
这篇关于Windows Unicode C ++流输出失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!