[C++基础]cout与wcout,printf与wprintf,ofstream与wofstream关于输出中文的问题解决
#include <iostream> #include <fstream> using namespace std; /*cout和wcout 在缺省的C locale下,cout可以直接输出中文,但对于wcout却不行(至少VS 2005下不行)。对于wcout,需要将其locale设为本地语言才能输出中文: wcout.imbue(locale(locale(),"",LC_CTYPE)); // ① 也有人用如下语句的,但这会改变wcout的所有locale设置,比如数字“1234”会输出为“1,234”。 wcout.imbue(locale("")); */ void DoCout() { cout<<"multibyte中文"<<endl; wcout<<"multibyte中文"<<endl; wcout.imbue(locale(locale(),"",LC_CTYPE)); // ① cout<<L"unicode中文"<<endl;//出现乱码,cout只能输出多字节的字符串,若是unicode的则会出现乱码,即使用wcout.imbue(locale(locale(),"",LC_CTYPE)); 也不行,所以只能把要输出的变量转变为ansi字节形式的 wcout<<L"unicode中文"<<endl;//中文输出不行,有wcout.imbue(locale(locale(),"",LC_CTYPE)); 则可以了 } /*ofstream和wofstream 在缺省的C locale下,ofstream能正确输出中文到文件中,但不支持中文文件名; wofstream支持中文文件名,但不能向文件中输出中文。 要解决这个 问题,需要在打开文件之前将全局locale设为本地语言。 将全局locale设为本地语言后,ofstream和wofstream的问题都解决了,但 cout和wcout却不能输出中文了。要让cout和wcout输出中文,需要将全局locale恢复原来的设置,如下所示: */ void DoFStream() { locale &loc=locale::global(locale(locale(),"",LC_CTYPE)); // ② ofstream ofs("ofs测试.txt"); wofstream wofs(L"wofs测试.txt"); locale::global(loc); // ③ ofs<<"test测试"<<1234<<endl; wofs<<L"Another test还是测试"<<1234<<endl; } /*printf和wprintf 缺省情况下,⑤、⑦两条语句不能输出中文,这两条语句中字符串的形式是unicode形式的。如果在所有输出语句之前加上如下语句将C语言的全局locale设置为本地语言(C语言中只有全局locale)就可以正常输出了: setlocale(LC_CTYPE,""); // ⑧ 但这会导致cout和wcout不能输出中文(汗,的确麻烦),将C语言的全局locale恢复后cout和wcout就正常了,如下所示: setlocale(LC_CTYPE, "C"); // ⑨ 但恢复后,printf和wprintf输出Unicode文本又不正常了(输出MultiByte文本总是正常的)。总不能每写一个 printf/wprintf就设置一次然后再恢复一次吧?所以,建议不要混用iostream和printf/wprintf,实在要混用,那就让 printf/wprintf只输出MultiByte字符串,这样不需要调用setlocale(),也就不会影响到cout和wcout. */ void DoPrintf() { setlocale(LC_CTYPE,""); // cout<<"multibyte中文\n"; // wcout<<"multibyte中文\n"; printf("%s", "multibyte中文\n"); // ④ printf("%S", L"unicode中文\n"); // ⑤ 有了setlocale(LC_CTYPE,"");则可以了 wprintf(L"%S", "multibyte中文\n"); // ⑥ wprintf(L"%s", L"unicode中文\n"); // ⑦ 有了setlocale(LC_CTYPE,"");则可以了 //%s:表明对应的字符串是ansi的;字符串 //%S:表明对应的字符串是Unicode的;wchar_t字符(宽字符)类型字符串 } void main() { DoCout(); DoFStream(); DoPrintf(); } /*总结 总之,用iostream、printf/wprintf输出中文,有点麻烦。概括起来要点如下: 如果要用wcout,需要在使用之前按语句①将其locale设置为本地语言; 如果要用ofstream或wofstream,要在打开文件之前按语句②将全局locale设为本地语言并保存初始的全局locale。然后在打开文件之后,按语句③将全局locale恢复为初始值; 不要混用iostream和printf/wprintf。如果要混用,只用printf/wprintf输出MultiByte字符串; 单独使用printf/wprintf时,如果要输出Unicode字符串,需要按语句⑧设置C语言的全局locale。如果只输出MultiByte字符串,则不需设置。 */