Code：Blocks 中文乱码问题原因分析和解决方法！ - softman11的专栏 - 博客频道 - CSDN.NET

# softman11的专栏

##

- 目录视图
- 摘要视图
- 订阅

用开源IaaS构建自己的云——OpenStack征稿启事 CSDN社区7月"畅谈加班 赢程序员杂志"活动火爆上线！！
2012年7月当选微软MVP的CSDN会员名单揭晓！ CSDN账号全站整合公告 不用买彩票，就有408万！

### Code：Blocks 中文乱码问题原因分析和解决方法！

2011-01-07 00:20 4161人阅读 评论(11) 收藏 举报

这里以Code::Blocks 10.5版本为蓝本进行说明。

首先，请在Code::Blocks里面输入标准的一个C程序：

[cpp] view plaincopyprint?

1. #include<stdio.h>
2. #include<stdlib.h>
3. #include<wchar.h>
4. #include<string.h>
5. #include<locale.h>
6. int main(void)
7. {
9. char str[]="中国china";
10. wchar_t str_w[]=L"中国china";
12. int len=(int)strlen(str);
13. int len_w=(int)wcslen(str_w);
14. printf("%s,size=%d/n",str,len);
16. setlocale(LC_ALL, "chs");
17. wprintf(L"%s,size=%d/n",str_w,len_w);
19. system("pause");
20. return 0;
21. }

#include<stdio.h> #include<stdlib.h> #include<wchar.h> #include<string.h> #include<locale.h> int main(void) { char str[]="中国china"; wchar_t str_w[]=L"中国china"; int len=(int)strlen(str); int len_w=(int)wcslen(str_w); printf("%s,size=%d/n",str,len); setlocale(LC_ALL, "chs"); wprintf(L"%s,size=%d/n",str_w,len_w); system("pause"); return 0; }

然后选用不同的编译器，观看效果。

1.Tiny C

编译没问题，但是wprintf是显示不出内容的。注释掉setlocale(LC_ALL,"chs“)之后，wprintf显示出和printf一样的效果。

结果证明，Tinny C是不真正的支持wchar_t宽字符集。因为通过调试器，我发现他的wchar_t里面保存的字符每个字符确实是用2个字节了，但是里面编码依然是 ANSI编码，并不是unicode代码，所以setlocale(LC_ALL,"chs“)+wprintf显示不出来(其实wprintf实现的时 候，是不会直接输出unicode的，他实际是先把unicode转成多字节的ANSI编码，然后再输出，和printf原理一样，就是多了一个转码过 程,所以你使用之前必须先设置locale,否则他不知道如何转，就输不出来)。

虽然他自称部分支持C99，但是至少在宽字符方面，支持的一点都不好。

Tinny C有一点好，他没有乱码，他要么不显示，要么正常显示。

2.VC2005-2010

一切OK，没有乱码。是支持wchar_t支持的最好的！

3.GCC(MinGW)

很遗憾，全是乱码！和java 一个德行（相信用过Java的人一定会想起Java的乱码解决花费的时间吧）。呵呵。但是GCC是支持wchar_t的，为什么会这样？其实根本原因就是：本地化做的不好。

但是解决方法是有的。

要解决这个问题，先要搞清楚有三个地方涉及到编码问题。

1.Code：:Blocks 编辑器保存源文件用的编码。

默认情况下，是保存为windows本地编码的，也就是WINDOWS-936字符集，也就是GBK编码。

但是很神奇的是，GCC编译器默认编译的时候是按照UTF-8解析的。你存成GBK，但是当成UTF-8解析，这还能编译通过，这才有鬼了，所以这两个地 方编码不统一好，编译的时候报错：error: converting to execution character set: Illegal byte sequence，你根本连通过编译的可能性都没有！

其实要解决这个问题很简单，编写Code：：Blocks的人只需要在调用编译器之前检测一下源文件是什么编码，然后就自动让编译器用什么编码进行 解释，问题就解决了。只是很可惜，Code::Blocks编写的人可能还没有这么做，或许是对本地化认识不够吧，也可能是觉得没必要吧？（所以就给初学 的人带来问题了，所以就觉得易用性不如微软了，免费和商业的东西还是有差距的。。。）

2。GCC编译器编译的时候对输入的源文件解释用的编码

这个编译器可以设置-finput-charset=charset来指定编译器用什么编码解释输入源文件。比如如果源文件的字符集是GBk,那么就必须指定-finput-charset=GBK,如果不指定，一律当做UTF-8处理。

除非你源文件真的是UTF-8，否则就会出现转换错误。

3。编译好的执行文件所用编码

如果你1和2两个地方的编码都能统一，那么编译时不会报错了，但是编译好了，运行一下看看，在控制台显示的依然是乱码！

那是因为控制台显示的时候缺省的是使用系统默认的字符集，比如windows下用的是GBk，但是默认情况下，编译之后的执行文件时编译成UTF-8的，所以又出现了不统一，乱码由此而生！

解决的方法和简单，就是给编译器加上选项：-fexec-charset=GBK，和windows默认的统一，就OK了。

搞懂了乱码产生的原因，那么不难得出结论，如何修改，你想修改成什么都OK，关键是要统一，并不是像网上一些人说的，修改成GBK就OK，其实你要修改成UTF-8都OK，关键是统一。

下面说说修改的地方。

1。修改源文件保存编码在：settings->Editor->gernal settings 看到右边的Encoding group Box了吗？如下图所示：

Use encoding when opening files:这个表示打开文件用的格式，第一次保存文件的时候也会用这个格式。

As default encoding:表示设置为文件缺省保存和打开编码格式

注意，要先设置好，然后保存文件，才有效。如果你已经保存了文件，无论你怎么修改这个设置，也不会改变你文件的格式了。你的文件还是保持第一次保存的时候的格式。

所以，如果遇到无法生效，只能先设置好格式，再重新建文件了。

2。修改编译器对源文件解释编码格式和生成执行文件执行时候采用的编码格式

是在settings->compiler and debugger settings里面，选择对应的GCC编译器，如下图所示：

在other options里面加入：

-finput-charset=charset

-fexec-charset=charset

第一个参数表示编译的时候输入文件的编码解释格式，第二参数表示生成的执行文件执行的时候显示用的编码格式。

这些参数如果和实际不吻合，必然产生乱码。只要吻合，就不会乱码了。

由于我的源文件格式是WINDOWS-936,但是这里设置成UTF-8，所以编译肯定报错！

只需要修改成-finput-charset=WINDOWS-936或者GBk，就编译通过了。

如果不设置fexec-charset默认会认为执行环境是UTF-8，而windows下并不是，所以Linux下没问题，因为Linux就是UTF-8的，但是windows 下必然出现乱码。

所以设置成GBk，就统一了。

一切都那么简单，其实，只是因为编程的人做的不够完善，所以才会给使用的人带来困扰。希望这篇文章能帮到一些初学者。或者遇到同样问题的人。

分享到：
- 上一篇： 寻找C/C++的净土!
- 下一篇： 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)
查看评论

10楼 diver492574562 2012-05-01 12:01发表 [回复] [引用] [举报]
  真心强大呀，知其然，知其所以然。

9楼 neodooth 2011-12-10 19:43发表 [回复] [引用] [举报]
  登录来感谢。

8楼 heshiip 2011-11-09 00:47发表 [回复] [引用] [举报]
  按照上述方法问题解决了，非常感谢！我在编程中遇到了2种中文乱码的情况：第一个是源代码文件乱码，也就是打开上次在Code::Blocks中写好的源代码，再次打开就会出现中文乱码。其二：程序中的中文字符常量在输出时会出现乱码。用作者所说方法，已经解决。

7楼 yageeart 2011-09-10 11:57发表 [回复] [引用] [举报]
  我按照您写的做了设置，包括Editor和compiler and debugger settings，并且用printf和wprintf都可以输出中文，但是用wcout却不可以。
  代码如下：
  [cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include<locale>
  3. int main(){
  4. setlocale(LC_ALL,"chs");
  5. wchar_t wt[]=L"中文";
  6. wcout<<wt;
  7. return 0;
  8. }

      #include <iostream>
      #include<locale>
      int main(){
          setlocale(LC_ALL,"chs");
          wchar_t  wt[]=L"中文";
         wcout<<wt;
         return 0;
      }

  我是C++初学者，问的问题可能存在一些低纸错误，但是我还是勇敢地贴出来，热切您能帮我解决这个问题。谢谢

Re: yageeart 2011-09-10 11:59发表 [回复] [引用] [举报]
  回复yageeart：补充：我使用的是code::blocks。看您的贴子，知道您是c类语言的大牛，希望能从您这里学习到更多的东西。

6楼 blueblizza 2011-07-29 12:06发表 [回复] [引用] [举报]
  多谢，学习了，非常有用

5楼 ldg2050 2011-05-03 23:00发表 [回复] [引用] [举报]
  多谢，正好看到了，才准备用CB

4楼 yui 2011-03-08 17:36发表 [回复] [引用] [举报]
  谢谢！补充一下，如果在非简体中文的Windows下，可能还需以下设置，需要管理员权限
  控制面板—区域语言选项
  1. 语言标签，勾选“东亚语言”
  2. 高级标签，为非unicode程序选择“China(PRC)”，同时确认勾选code pages 936

3楼 xzlcc 2011-03-04 17:53发表 [回复] [引用] [举报]
  thank you ,study

2楼 vanxining 2011-03-04 10:34发表 [回复] [引用] [举报]
  多谢，学习了

1楼 lipent 2011-01-26 13:12发表 [回复] [引用] [举报]
  多谢，学习了，

您还没有登录,请[登录]或[注册]
* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场

个人资料

softman11

- 访问：11572次
- 积分：299分
- 排名：千里之外

- 原创：16篇
- 转载：2篇
- 译文：0篇
- 评论：20条

文章搜索

文章分类

- java(0)
- Linux(0)

阅读排行

- Code：Blocks 中文乱码问题原因分析和解决方法！(4161)
- C#中删除任意控件任意事件的事件列表的实现！(1739)
- 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)(1214)
- .net中StopWatch的计算时间频率的问题！(461)
- 转帖一篇sixxpack破解的文章！(447)
- 寻找C/C++的净土!(340)
- 关于C和C++，还有c#,还有java程序的速度问题！(328)
- Windows系统消息机制的详细理解！(318)
- 转载一篇ClickOnce的文章！(244)
- 关于不同的编译器使用过程中遇到的问题！(244)

评论排行

- Code：Blocks 中文乱码问题原因分析和解决方法！(11)
- 转帖一篇sixxpack破解的文章！(3)
- 关于不同的编译器使用过程中遇到的问题！(2)
- 寻找C/C++的净土!(2)
- 关于C和C++，还有c#,还有java程序的速度问题！(二）(1)
- 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)(1)
- .net 程序的的保护是个大问题！(0)
- 关于C和C++，还有c#,还有java程序的速度问题！(三）(0)
- 关于C和C++，还有c#,还有java程序的速度问题！(0)
- 软件版本标识知识总结！(0)

推荐文章

最新评论

- Code：Blocks 中文乱码问题原因分析和解决方法！

  diver492574562: 真心强大呀，知其然，知其所以然。

- 寻找C/C++的净土!

  sagetom: 赞一个，使用code:blocks爽字了得。

- 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)

  turtle_2: 这么好的文章，难道没人评论吗？ 还是不能评论啊。多谢博主！

- 寻找C/C++的净土!

  tsummer2010: 看了你的这篇文章我就用code blocks了vs2010我也装了，但运行太慢，一般不用

- Code：Blocks 中文乱码问题原因分析和解决方法！

  neodooth: 登录来感谢。

- Code：Blocks 中文乱码问题原因分析和解决方法！

  heshiip: 按照上述方法问题解决了，非常感谢！我在编程中遇到了2种中文乱码的情况：第一个是源代码文件乱码，也就是...

- 关于不同的编译器使用过程中遇到的问题！

  Funniest: 正在学习tcc，顶一下

- 关于C和C++，还有c#,还有java程序的速度问题！(二）

  yageeart: 问个题外话，看到中科院有位老师在其课程中说到，他不喜欢用float，在您这篇贴子中看到也是用doub...

- Code：Blocks 中文乱码问题原因分析和解决方法！

  yageeart: @yageeart:补充：我使用的是code::blocks。看您的贴子，知道您是c类语言的大牛，希...

- Code：Blocks 中文乱码问题原因分析和解决方法！

  yageeart: 我按照您写的做了设置，包括Editor和compiler and debugger settings...

  公司简介|招贤纳士|广告服务|银行汇款帐号|联系方式|版权声明|法律顾问|问题报告
  京 ICP 证 070598 号
  北京创新乐知信息技术有限公司 版权所有
  联系邮箱：webmaster@csdn.net
  Copyright © 1999-2012, CSDN.NET, All Rights Reserved