中文乱码如何解决(中文乱码的原因,以及如何避免)

中文乱码如何解决(中文乱码的原因,以及如何避免) 

前言

初学者在Windows平台上进行C/C++语言(中文)程序开发时,有时会遇到编译报错、在控制台运行时显示中文乱码的问题。

本文就此类问题进行描述、展开原因分析,然后给出解决方法。

本次分享内容的目录如下:

基本概念(字符集、字符编码、代码页、GBK、UTF-8)

问题描述(示例源码、编译报错、中文乱码)

原因分析(编码环节简介、原因分析)

解决方法(解决思路、编译报错解决、中文乱码解决)

结束语


1. 基本概念

中文乱码如何解决(中文乱码的原因,以及如何避免) 

本文会涉及到如下基本概念:

1.1 Charset(字符集)

Charset(字符集):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。常见的字符集有:ASCII字符集、Unicode字符集等。

计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。

1.2 Character Encoding(字符编码)

Character Encoding(字符编码)用于为指定集合中某一对象(如电脉冲、比特模式等),以便文本在计算机中存储和通过通信网络的传递。字符编码就是将符号转换为计算机可以接受的数字系统的数。常见的例子:将拉丁字母表编码成ASCII。

注:术语字符编码(Character Encoding)、字符映射(Character Map)或者代码页(CodePage),在历史上往往是同义概念,即字符表(repertoire)中的字符如何编码为码元的流(stream of code units)–通常每个字符对应单个码元。

1.3 CodePage(代码页)

CodePage(代码页)是字符编码的别名,也称内码表,是特定语言的字符集的一张表。

  • OEM(IBM PC)代码页:指计算机的BIOS所支持的字符集编码。最具代表性的是”代码页437(IBM PC或MS-DOS )”。
  • Windows(ANSI)代码页:微软针对不同的使用地区与国家,定义了一系列的支持不同语言字符集的代码页。最具代表性的是代码页WINDOWS-1252 (实现了ISO-8859-1)。

注:Windows代码页最初是根据ANSI草案实现的,这个草案最终成为ISO 8859-1。这是Windows代码页被称作ANSI的缘由。

本文涉及到的两个重要代码页介绍如下:

  • 代码页936:该代码页对应的是GBK编码。既是OEM代码页,也是ANSI代码页。
  • 代码页65001:该代码页对应的是UTF-8编码。

Windows平台上的GUI程序使用ANSI代码页,而在控制台程序使用OEM代码页(以便向后兼容)。

在Windows系统中的命令行窗口可以通过chcp命令来显示当前代码页(如Windows 7 简体中文操作系统上默认的代码页是936):

 C:> chcp
 活动代码页: 936

也可以通过在chcp命令后带一个具体整数参数(代码页数值)来临时改变命令行窗口的当前代码页(如临时修改为UTF-8对应的65001):

 C:> chcp 65001
 Active code page: 65001

1.4 GBK(汉字内码扩展规范)

GBK(英文全称:Chinese Internal Code Extension Specification,中文全称:汉字内码扩展规范)是对GB2312-80的扩展,也就是代码页936的扩展(之前代码页936和GB2312-80一模一样),最早实现于Windows 95简体中文版。

GBK总体编码范围为0x8140~0xFEFE,首字节在 0x81~0xFE 之间,尾字节在 0x40~0xFE 之间,剔除 xx7F 一条线。GBK共收录21886个汉字和图形符号,其中汉字(包括部首和构件)21003个,图形符号883个。

后续国家标准GB18030技术上兼容GBK。

注:微软Windows安排给GBK的代码页是936,所以编码格式WINDOWS-936其实就是GBK。

1.5 UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对 Unicode 的可变长度字符编码。它可以用一至四个字节对 Unicode字符集中的所有有效编码点进行编码,属于Unicode 标准的一部分。

自2009年以来 UTF-8一直是互联网上使用最广的一种编码方式。


2. 问题描述

中文乱码如何解决(中文乱码的原因,以及如何避免) 

初学者在Windows平台上进行C/C++语言(中文)程序编程开发时,有时会遇到编译报错、在控制台执行时显示中文乱码的问题。

2.0 示例源码

下面用于示例的一个C语言源代码文件(功能:从控制台显示一段中英文信息。)

 #include <stdio.h>
 
 int main(void)
 {
     printf("+++++++++++++++++++++++++++n");
     printf("++  Hello, C语言开发者!  ++n");
     printf("+++++++++++++++++++++++++++n");
 
     return 0;
 }

2.1 编译报错

第一类问题是:在编译时发现报错,报错信息如下:

 hello.c: In function 'main':
 hello.c:6:12: error: converting to execution character set: Illegal byte sequence
      printf("++  Hello, C语言开发者!  ++n");
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2.2 中文乱码

第二类问题是:能顺利通过编译生成可执行文件,但该可执行文件在Windows控制台上运行时显示中文乱码,如下图示:

中文乱码如何解决(中文乱码的原因,以及如何避免)控制台显示中文乱码1

或:

中文乱码如何解决(中文乱码的原因,以及如何避免)控制台显示中文乱码2


3. 原因分析

中文乱码如何解决(中文乱码的原因,以及如何避免) 

Windows平台C/C++语言(中文)程序编译报错、在控制台执行时显示中文乱码一般都是由于编码不一致所引起的。

3.1 编码环节简介

首先,我们来看看在 Windows 平台上开发运行一个C/C++语言程序的全过程(源文件编辑、编译、运行)中主要涉及的编码环节有哪些?

中文乱码如何解决(中文乱码的原因,以及如何避免)C语言开发全过程涉及的编码环节

环节一、源代码保存时的字符编码

  • 描述:指编辑器在保存源代码文件所使用的字符编码。
  • 默认编码:Windows平台上默认是保存为Windows本地编码,即WINDOWS-936代码页,也就是GBK编码。
  • 编码设置:可以通过编辑器设置来更改源文件保存编码,如保存为UTF-8编码。

环节二、编译器编译时的输入文件(源文件)字符编码

  • 描述:GCC编译器编译时对输入的源码文件解析时用的字符编码。
  • 默认:GCC编译器编译时对输入文件默认是按照UTF-8编码解析的。
  • 编码设置:可以通过设置编译器选项-finput-charset=<charset>来指定编译器用什么编码解析输入的源文件。
  • 示例:-finput-charset=GBK

环节三、编译器编译好的输出文件(可执行文件)字符编码

  • 描述:GCC编译器编译好的输出文件(可执行文件)所用的字符编码。
  • 默认:GCC编译器默认为UTF-8编码。
  • 编码设置:GCC编译器可以通过设置-fexec-charset=<charset>选项来指定编译器用什么编码显示输出执行文件。
  • 示例:-fexec-charset=GBK

环节四、控制台使用的字符编码

  • 描述:控制台在显示所用的编码。
  • 默认:Windows平台控制台默认使用WINDOWS-936代码页(即GBK编码);Linux控制台默认使用UTF-8编码。
  • 编码设置:Windows平台可以通过注册表编辑器来指定控制台用什么编码显示输出执行文件。

3.2 原因分析

Windows平台C/C++语言(中文)程序编译报错、在控制台执行时显示中文乱码一般都是由于编码不一致所引起的。

中文乱码如何解决(中文乱码的原因,以及如何避免)原因分析

3.2.1 编译报错原因分析

从上图可以很清晰的看出编译报错的原因是在环节一与环节二两处的编码不一致(如下)所引起的:

(一)上图中的1与4的组合(源文件保存为UTF-8编码,但GCC编译器对输入文件-源文件设置的是按GBK编码解析)

(二)上图中的2与3的组合(源文件保存为GBK编码,但GCC编译器对输入文件-源文件设置的是按UTF-8编码解析)

3.2.2 中文乱码原因分析

从上图可以很清晰的看出中文乱码的原因是在环节三与环节四两处的编码不一致(如下)所引起的:

(一)上图中的5与8的组合(GCC编译器对输出执行文件设置的是UTF-8编码,但Windows控制台是GBK编码)

(二)上图中的6与7的组合(GCC编译器对输出执行文件设置的是GBK编码,但Windows控制台是UTF-8编码)


4. 解决方法

中文乱码如何解决(中文乱码的原因,以及如何避免) 

4.1 解决思路

通过上述原因分析,已经发现了编译报错和中文乱码的问题根源所在:前后环节的编码不一致造成。

既然问题根源找到了,那么解决思路也就迎刃而解了(如下图示):

中文乱码如何解决(中文乱码的原因,以及如何避免)解决思路

一、在环节一和环节二之间保持两者编码的一致性(1和3组合,或2和4组合)进而解决编译报错问题;

二、在环节三和环节四之间保持两者编码的一致性(5和7组合,或6和8组合)进而解决中文乱码问题。

4.2 编译报错解决

针对编译报错的两种情形(1和4组合、2和3组合)具体解决办法是:

4.2.1 方法一(1和3组合)

修改源文件编码为UTF-8编码,以跟GCC编译器对输入文件-源文件默认UTF-8编码解析保持一致。

修改源文件编码为UTF-8编码的具体步骤如下:

中文乱码如何解决(中文乱码的原因,以及如何避免)修改源文件编码为UTF-8编码

  • Step1:通过执行Code::Blocks软件的菜单栏【设置】下的【编辑器】子菜单项,进入“编辑器配置”窗口。
  • Step2:点击左侧【常规设置】按钮(上图标号1处),继续点击右侧的【编码设置】选项卡(上图标号2处)
  • Step3:在使用编码右侧的下拉框中选择【UTF-8】(上图标号3处)
  • Step4:选中【设为默认的编码方式(忽略C::B的自动检测)】(上图标号4处)
  • Step5:点击右下角的【确定】按钮,完成编辑器编码设置。
  • Step6:然后将编辑器内的源文件稍加修改重新保存(保险起见,可以重启 code::Blocks软件以确保源文件编码生效)。

4.2.2 方法二(2和4组合)

修改源文件编码为GBK编码,将GCC编译器对输入文件-源文件设置为是按GBK编码解析。

一、修改源文件编码为GBK编码的具体步骤

与上面类似(在下拉框中把UTF-8改为WINDOWS-936即可)。

中文乱码如何解决(中文乱码的原因,以及如何避免)修改源文件编码为GBK编码

二、修改编译器对输入源文件的解析编码为GBK编码的具体步骤如下:

中文乱码如何解决(中文乱码的原因,以及如何避免)修改编译器输入编码设置

  • Step1:通过执行Code::Blocks软件的菜单栏【设置】下的【编译器】子菜单项,进入“编译器设置”窗口。
  • Step2:点击左侧【全局编译器设置】按钮(上图标号1处),继续点击右侧的【编译器设置】选项卡(上图标号2处)
  • Step3:再继续点击下方的【其他编译器设置】选项卡(上图标号3处)
  • Step4:在下面的文本框中直接输入-finput-charset=GBK(上图标号4处)
  • Step5:点击右下角的【确定】按钮,完成编译器输入编码设置。

验证:经过前面两种方法的设置,完成编码一致性后,再次进行编译,就已经可以成功通过了(如下图示)。

中文乱码如何解决(中文乱码的原因,以及如何避免)编译成功但显示乱码

但是你会发现程序运行在控制台时显示中文乱码了。

此时再回想一下:源文件编码(GBK)+ 编译器输入设置编码(GBK) = 编译通过。但因为GCC编译器默认输出执行文件编码为UTF-8编码,同时Windows控制台默认是GBK编码,所以此时程序运行在控制台显示中文乱码逻辑上是正常的。

4.3 中文乱码解决

针对中文乱码的两种情形(5和8组合、6和7组合)具体解决办法是:

4.3.1 解决方法一(6和8组合)

设置GCC编译器对输出执行文件是GBK编码,跟Windows控制台默认GBK编码保持一致。

修改编译器对输出执行文件编码为GBK编码的具体步骤如下:

中文乱码如何解决(中文乱码的原因,以及如何避免)修改编译器输出编码设置

  • Step1:通过执行Code::Blocks软件的菜单栏【设置】下的【编译器】子菜单项,进入“编译器设置”窗口。
  • Step2:点击左侧【全局编译器设置】按钮(上图标号1处),继续点击右侧的【编译器设置】选项卡(上图标号2处)
  • Step3:再继续点击下方的【其他编译器设置】选项卡(上图标号3处)
  • Step4:在下面的文本框中直接输入-fexec-charset=GBK(上图标号4处)
  • Step5:点击右下角的【确定】按钮,完成编译器输出编码设置。

4.3.2 解决方法二(5和7组合)

修改Windows控制台编码为UTF-8编码,以跟GCC编译器对输出执行文件默认UTF-8编码保持一致。

修改Windows控制台编码为UTF-8编码的具体步骤如下:

  • Step1:通过快捷键Win+R,弹出的【运行】窗口中,执行regedit命令,然后点击【确定】按钮打开“注册表编辑器”窗口。
中文乱码如何解决(中文乱码的原因,以及如何避免)运行regedit命令

  • Step2:在“注册表编辑器”窗口中依次点击【计算机】(下图标号1)、【HKEY_CURRENT_USER】(下图标号2)、【Console】(下图标号3)
中文乱码如何解决(中文乱码的原因,以及如何避免)进入注册表编辑器查找

  • Step3:在右侧选中【CodePage】项,然后双击弹出“编辑 DWORD(32位)值”窗口,依次选择【十进制】(下图标号1处)、把“数值数据”下的 936 修改为 65001(下图标号2处)。
中文乱码如何解决(中文乱码的原因,以及如何避免)修改注册表项

  • Step4:点击上图【确定】按钮,完成修改(如下图示)。
中文乱码如何解决(中文乱码的原因,以及如何避免)修改注册表完成

  • Step5:按【快捷键F5】进行刷新生效。

注1:如果要恢复原数值只需重复同样的步骤,把65001修改为936即可。

注2:上面方法面向所有的控制台(如:Windows默认CMD控制台、CodeBlocks控制台、DevCpp控制台、Git CMD控制台等)生效。

注3:如果只需针对特定控制台生效,可以在本步骤基础上,再往下一层,选中具体控制台(如【
C:_Develop_CodeBlocks_cb_console_runner.exe】),然后通过鼠标右键菜单新建一个【DWORD(32位)值】,该数值名称设为【CodePage】,数值数据设为【65001】(十进制)。然后【F5】刷新即可生效。


验证:经过上面两种方法的设置,完成编码一致性后,再次在控制台运行软件时就已经是正常显示中英文了(如下图示):

中文乱码如何解决(中文乱码的原因,以及如何避免)编译、运行显示正常

注:本文虽是以Code::Blocks集成开发环境为例进行讲解,但其原理针对Windows平台上C语言程序运行的其他控制台(如Windows默认CMD控制台、Git CMD控制台等)也是适用的。


结束语

相信各位 C 语言初学者们阅读完本文后,应该已经对 Windows 平台C语言(中文)程序在编译时报错的原因及解决办法、在控制台运行时显示中文乱码的原因及解决办法已经有了比较基本的了解掌握,此类问题将不再困扰,接下来就可以愉快地学习其他 C 语言知识了。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。爱坤分享仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 3252784850@qq.com 举报,一经查实,本站将于三个工作日内删除。文章链接:https://www.sfyjdwx.com/n/54110.html

(0)

相关推荐

  • 见鬼之灵魂摆渡人(见鬼之灵魂摆渡演员表)

    灵异网剧《灵魂摆渡》是国内首部“以鬼说人”的悬疑灵异题材网络剧, 该剧讲述了阴阳眼少年冬青与灵魂摆渡人赵吏,一同帮助因有心事未了而滞留人间的灵魂的故事。影片表现手法上的多元化更加凸显了其多元血统,编剧非常好地把握了“惊悚”和“正能量”之前的平衡,在剧集的大部分故事中设置了巧妙的悬念与转折,总是能将包裹在惊悚氛围中的剧情最终引导到充满温情正能量或是批评社会负面…

    2022-11-21
    28
  • 数30怎么玩必赢数三个数(数30怎么玩必赢2人)

    在前一篇里说过,对于数数游戏:甲乙两人轮流数数,依次从1开始数到30,每次最少要一个数最多只能数两个连续的数数,谁数到30就输(或赢)。若是超过3人玩则无法保证任一方百分百获胜。 规则还是一样的,甲乙丙三人轮流数数,依次从1开始数到30,每次可以数一个数或两个连续的数数,谁数到30就输(或赢)。 首先以谁数到30就输来看看: 1、三人中某一人若要保证自己不会…

    2022-12-22
    12
  • 宣纸得名于它的什么(宣纸得名于它的用途还是产地)

    每日一题 5/13       宣纸,产于安徽宣州泾县,在宣城集散而得名。泾县附近地区也生产这种纸。 2009年9月30日,宣纸获联合国教科文组织肯定,列入人类非物质文化遗产名录。宣纸的原料是青檀皮,清代时才掺和稻草,改变了用料比例。 宣纸起于唐代,历代相沿。由于宣纸有易于保存,经久不脆,不会褪色等特点,故有“纸寿千年”之誉。 …

    2022-11-21
    13
  • 男人一生最吉利的网名两个字(男人一生最吉利的网名4个字)

    反正你早晚都要谈恋爱,跟我在一起怎么了?一组男生的好听的两个字网名送给大家,都是两个字的,很好听哦! 男爵 清醒 缨璃 尤洒 笙北 苏北 江山 江愁 晴天 鲸落 青迟 柚屿 忆忧 希年 栀柚 烟北 尘笙 着迷 惊鸿 余悸   阔以椿湫余罪封笔半島城北殊途故里逆袭川暮孤猫空心阡陌無心獨爱化风饭团爱卿直男奔赴木兮   暖阳废清迟暮归安九月忆夏…

    2022-11-23
    16
  • 世界杯历届冠军榜排名(世界杯历届冠军列表)

    2022年卡塔尔世界杯正在火热举办,足球世界杯已成功举办21届 世界杯历代冠军如下: 1、1930年乌拉圭世界杯,冠军→乌拉圭; 2、1934年意大利世界杯,冠军→意大利; 3、1938年法国世界杯,冠军→意大利; 4、1950年巴西世界杯,冠军→乌拉圭; 5、1954年瑞士世界杯,冠军→德国; 6、1958年瑞典世界杯,冠军→巴西; 7、1962年智利世界…

    2022-12-03
    16
  • 怎么看qq聊天记录保存在哪里(手机qq聊天记录保存在哪里)

    微信和QQ可以怎么查找聊天记录呢,以下的内容告诉你。首先需要打开微信或者QQ按着下面的操作来就可以了,详细的往下看哦! 如果以上方法还是找不到聊天记录的话,需要借助手机数据恢复服务来进行恢复了,适合不想求人,想要速度快,安全,可靠的就可以选择数据恢复服务了。不但可以恢复微信QQ的聊天记录,还有视频图片、通讯录、短信、好友误删同样可以恢复,同时还有数据的导出,…

    2022-11-23
    29
  • 白金k金跟铂金是一回事吗(白银k金和铂金是一回事吗)

    金是最名贵的金属之一,在首饰制作中被广泛应用。然而纯金有着质地过软的性质,只能用做一般首饰,而不能进行更复杂的 设计,K金由此诞生! .   1️⃣什么是K金? K金是在黄金中添加其他金属,达到丰富颜色的同时还能提高硬度的效果,调色后的K金又叫彩金。 . 2️⃣主要彩18K金的构成 18K白色K金:75%金+25%银、镍+锌组合而成(镍不得超0.3…

    2022-11-28
    9
  • 500克是多少斤两(500克是多少毫升)

    过年比较有意思的事情之一就是一群狐朋狗友聚在一块,打打牌,喝点小酒,顺带吹吹牛,然后互相拆拆台。 说到喝酒,不知你们那的习俗是怎样的,反正我们这一到喝酒总能扯到酒量上来,说谁谁上的酒量大,谁谁谁多么能喝。 ​   比如经典的一段话: 我有个朋友,酒量真大,能喝一斤! 一个人喝一斤?吹吧! 真的,喝了一瓶! 一瓶也不是一斤啊…… 你看看,这不嘛,瓶子…

    2022-11-24
    25
  • ps怎么换发型女生(ps怎么换发型教程)

    在日常的生活中,当你站在镜子前看着自己乱糟糟的头发,突然想要去理发,但是你是否有以下这些困扰,不知道自己要剪什么发型、什么发型适合自己的、剪完好不好看等等的问题,怎么办呢,怎样才能剪出适合自己的发型呢?这时可以使用换发型的特效来让你不再困扰,那换发型特效怎么制作呢?接下来就一起来看看具体操作步骤吧!   方法一:可以借助“Styler”去实现换发型…

    2022-12-06
    24
  • 修改手机时间怎么修改(苹果手机时间怎么修改)

      iOS 15 终于内建修改照片日期、时间与地点的功能,意味着未来拍完之后,如果你因为某些原因想要修改,直接透过照片 App 即可,不用再另外下载 App,如果你还不知道怎么使用,下面就来教你 iOS 15 调整 iPhone 照片日期、时间、地点的方法。 – iOS 15 调整 iPhone 照片日期、时间的操作步骤 只要升级到 i…

    2023-01-28
    4