ofstream和wofstream与中文输出问题

转载文章地址:http://hi.baidu.com/vfishg/item/81ddb9271835fbf951fd8765

使用C++标准库的iostream,可以方便地将控制台、文件、字符串以及其它可扩充的外部表示作为流来处理,但要处理中文,却会碰到很多问题。 本人原来没怎么用过这个iostream,这几天尝试用这个写点东西,一会儿不能输出中文,一会儿不支持中文文件名的,搞得头大。网上搜了搜,没有发现适 用于所有情况的解决方案。不过后来自己经过多次测试,基本解决了这些问题,现在写成文字作为一个总结,也供碰到同样问题的朋友参考。关于C语言中的 printf和wprintf的中文输出,本文也进行了探讨。

需要说明的是,我的开发环境是VS 2005(标准库当然也是微软实现的),不保证其它环境下是相同的效果

  1. cout和wcout在缺省的C locale下,cout可以直接输出中文,但对于wcout却不行(至少VS 2005下不行)。

    对于wcout,需要将其locale设为本地语言才能输出中文:

    wcout.imbue(locale(locale(),"",LC_CTYPE)); // 1

    也有人用如下语句的,但这会改变wcout的所有locale设置,比如数字“1234”会输出为“1,234”。

    wcout.imbue(locale(""));
  2. ofstream和wofstream在缺省的C locale下,ofstream能正确输出中文到文件中,但不支持中文文件名;wofstream支持中文文件名,但不能向文件中输出中文。

    要解决这个 问题,需要在打开文件之前将全局locale设为本地语言。将全局locale设为本地语言后,ofstream和wofstream的问题都解决了。
    但 cout和wcout却不能输出中文了。要让cout和wcout输出中文,需要将全局locale恢复原来的设置,如下所示:

    locale &loc=locale::global(locale(locale(),"",LC_CTYPE)); // 2
    ofstream ofs("ofs测试.txt");
    wofstream wofs(L"wofs测试.txt");locale::global(loc); // 3
    ofs<<"test测试"<<1234<<endl;
    wofs<<L"Another test还是测试"<<1234<<endl;
  1. printf和wprintf

    加上这两位C语言中的老兄,问题更加复杂。考虑如下语句(注意s的大小写):

    printf("%s", "multibyte中文\n"); // 4
    printf("%S", L"unicode中文\n"); // 5
    wprintf(L"%S", "multibyte中文\n"); // 6
    wprintf(L"%s", L"unicode中文\n"); // 7

    缺省情况下,⑤、⑦两条语句不能输出中文,这两条语句中字符串的形式是unicode形式的。

    如果在所有输出语句之前加上如下语句将C语言的全局locale设置为本地语言(C语言中只有全局locale)就可以正常输出了:

    setlocale(LC_CTYPE, ""); // 8

    但这会导致cout和wcout不能输出中文(汗,的确麻烦),将C语言的全局locale恢复后cout和wcout就正常了,如下所示:

    setlocale(LC_CTYPE, "C"); // 9

    但恢复后,printf和wprintf输出Unicode文本又不正常了(输出MultiByte文本总是正常的)。总不能每写一个 printf/wprintf就设置一次然后再恢复一次吧?所以,建议不要混用iostream和printf/wprintf,实在要混用,那就让 printf/wprintf只输出MultiByte字符串,这样不需要调用setlocale(),也就不会影响到cout和wcout。

总之,用iostream、printf/wprintf输出中文,有点麻烦。概括起来要点如下:

  1. 如果要用wcout,需要在使用之前按语句(1)将其locale设置为本地语言;
  2.  如果要用ofstream或wofstream,要在打开文件之前按语句(2)将全局locale设为本地语言并保存初始的全局locale。然后在打开文件之后,按语句(3)将全局locale恢复为初始值; 
  3. 不要混用iostream和printf/wprintf。如果要混用,只用printf/wprintf输出MultiByte字符串;单独使用printf/wprintf时,如果要输出Unicode字
时间: 2024-11-03 21:45:40

ofstream和wofstream与中文输出问题的相关文章

wofstream,wcout无法输出unicode的真相

之前我转载过一篇ofstream和wofstream与中文输出问题,让我初步知道如何解决这类问题.第一次我没有在意,按照文章中做的方法去做,然后程序就运行正常了.我试图去记住这些规则,但是我后来发现,太难了.以至于我在最近一次使用到 std::wofstream 类的时候,发现我无法往其中输入unicode字符.让我找了几个小时的bug,于是我今天就花了两个小时,在网上搜索资料,以及自己写一些测试工程,调试跟踪 std::wofstream 的相关函数,差不多明白了原因.下面让我用最简单的方式,

在Unix/Linux上令(java)JVM支持中文输出

unix|中文 原文: 在Unix/Linux上令(java)JVM支持中文输出 一.在Unix/Linux上令JVM支持中文输出 如果用户使用的是UNIX的远程服务器,就会遇到中文字体在图像中输出的问题,特别是由于许多管理员并不喜欢把主机的locale定为zh(因为意味着可能出乱码或必须装微形图形终端象zhcon,但很多情况下这样的条件并不具备).大部分程序员的JAVA经验苟限于JSP脚本程序,部分熟练的程序员大概开发过中间件.servlet.applet或在WINDOWS上运行的GUI程序.

python实现中文输出的两种方法

  这篇文章主要介绍了python实现中文输出的两种方法,实例分析了Python操作中文输出的技巧,需要的朋友可以参考下 方法一: 用encode和decode 如: ? 1 2 3 4 5 6 7 8 9 10 11 import os.path import xlrd,sys Filename='/home/tom/Desktop/1234.xls' if not os.path.isfile(Filename): raise NameError,"%s is not a valid fil

iOS开发之网络数据解析--中文输出

对于服务器返回的数据,解析之后直接打印,如果数据中原本有中文,可能会出现中文乱码的结果:   为了避免这个问题,可以通过类别来重写系统和打印相关的方法. 步骤: 1.新建文件名:Foundation+Log的.m后缀的这一个文件,你没看错,就这个.m文件,不需要.h声明文件 2.然后把以下源码全部拷贝进去即可: // // NSDictionary+Log.m // 01-掌握-多值参数和中文输出 // #import <Foundation/Foundation.h> // 重写系统的打印方

visual studio-vs mfc中cfile read读取txt中文输出时乱码

问题描述 vs mfc中cfile read读取txt中文输出时乱码 解决方案 http://blog.csdn.net/augusdi/article/details/8961008http://bbs.csdn.net/topics/390192613

css-哪句话限制了中文输出吗?

问题描述 哪句话限制了中文输出吗? body {font-family:Arial, Helvetica, sans-serif,楷体,宋体,微软雅黑; font-size:100%; color:#333; min-width:960px; background:#f1f1f1} .ic {border:0;float:right;background:#fff;color:#f00;width:50%;line-height:10px;font-size:10px;margin:-220%

浅谈PDFlib中文输出(二)如何在PDFlib中使用其他简体中文字体

除了PDFlib自带字体外,用户还可以使用安装在系统上的字体及其他用户字体. PDFlib称安装在Windows和Mac操作系统中的(存在于或被拷入相应系统字体目录的)TrueType, OpenType 和PostScript字体为宿主字体(Host Font).PDFlib可直接引用字体名进行调用,但必须与文件名完全相同(严格区分大小写).例如,调用安装在Windows系统中的字体: C:\WINDOWS\Fonts\SimHei.ttf int Font_CS = 0; Font_CS =

浅谈PDFlib中文输出(三)PDFlib 的几种文本输出函数

1.PDF_show void PDF_show(PDF *p, const char *text) void PDF_show2(PDF *p, const char *text, int len) 在当前坐标用当前字体及字体大小输出文本. PDF_show将认为字符串是以空字符结尾(NULL):若字符串有可能含有空字符(如多字节字符串),用PDF_show2. 2.PDF_show_xy void PDF_show_xy(PDF *p, const char *text, double x,

浅谈PDFlib中文输出(一)如何使用Acrobat标准的简体中文字体

PDF文件格式以其安全可靠,易于交换,及保真度高而成为电子文档的标准.PDFlib是一套在国际上非常流行的在服务器端批量生成PDF文档的功能强大的软件包.国外许多政府,税务,银行,水电,邮电部门用其在线生成PDF格式的单据及报表. 对于国内用户来说,如何使用PDFlib输出简体中文会是我们最关心的问题.在这里我将于大家一起分享自己的一些心得体会,不对之处请指正,若我所说于PDFlib手册有冲突,请以手册为准.我的邮箱是 :bowriver2001@yahoo.ca . 对于没有接触过PDFlib