关于字符集和乱码的思考
c语言乱码问题详解

c语言乱码问题详解在C语言编程中,乱码问题是一个非常常见的问题。
乱码通常是指在显示或输出字符串时,字符的编码格式不正确,导致字符无法正常显示。
这个问题可能由多种原因引起,本文将对C语言乱码问题进行全面详解。
一、乱码的产生原因1. 编码格式不统一:在C语言编程中,字符串通常使用ASCII编码或UTF-8编码。
如果不同程序或不同文件使用了不同的编码格式,就可能导致乱码。
2. 文件编码不统一:在编写和读取文件时,如果文件本身的编码格式与程序使用的编码格式不统一,也可能导致乱码。
3. 代码页设置不正确:在Windows系统中,代码页设置不正确可能导致乱码。
例如,默认的代码页是936(简体中文),如果设置为其他代码页,就可能导致乱码。
二、乱码的解决方案1. 统一编码格式:在编写程序时,确保所有文件和使用到的库都使用相同的编码格式。
通常建议使用UTF-8编码,因为它可以很好地表示各种字符集,包括简体中文、繁体中文和英文等。
2. 使用正确的代码页:在Windows系统中,确保代码页设置正确。
可以通过修改系统设置或编程时使用`SetConsoleOutputCP()`函数来设置代码页。
3. 使用字符串处理库:对于复杂字符集的支持,可以使用第三方字符串处理库,如iconv或ICU。
这些库可以提供丰富的字符编码转换功能,帮助解决乱码问题。
4. 使用命令行参数:在编写程序时,可以使用命令行参数来指定输入和输出文件的编码格式。
这样,即使在不同环境中运行程序,也可以确保编码的一致性。
三、案例分析下面我们通过一个简单的案例来说明如何解决C语言中的乱码问题。
假设我们有一个简单的C语言程序,用于将一个文本文件的内容读取到一个字符串数组中,然后输出到另一个文本文件。
在编写这个程序时,我们需要注意以下问题:1. 统一编码格式:确保源文件和使用到的库都使用UTF-8编码。
2. 使用正确的代码页:在Windows系统中,确保代码页设置为UTF-8(1200)。
字符编码与解码,乱码原因分析

字符编码与解码,乱码原因分析最近遇到⼀个关于字符编码与解码的问题,使⽤GB2312保存了⼀个⽂件,然后使⽤vscode打开的时候,发现中⽂字符全是乱码了。
为什么会出现这个问题?研究了⼀下编码与解码。
⽂件在计算机上存储的都是⼆进制。
顾名思义,编码就是把⼀个字符编码成⼆进制码存起来的⽅式,⽽解码就是把这个⼆进制码按照原本编码的规则还原成原来的字符。
我们经常使⽤的ASCII码,是上个世纪60年代美国制定的⼀套字符编码,它规定了英语字符与⼆进制位之间的关系,⼀直沿⽤⾄今。
ASCII 码⼀共规定了128个字符的编码。
ASCII使⽤⼀个字节来进⾏编码,⼀个字节有8个bit位,ASCII只使⽤了后⾯的7个bit位,最前⾯的⼀个bit位使⽤0填充。
⼀些欧洲国家发现ASCII编码的128个字符不能表⽰他们的语⾔的所有的字符,所以他们决定启⽤最前⾯的⼀位,这样⼀来,就可以编码256个字符了,⽐以前⼜多了128个字符可以使⽤。
但是⼜有问题出现了,不同的国家的字母不⼀样,他们启⽤最⾼位来进⾏编码,不同的语⾔有不同的编码⽅式,导致了同样的编码在不同的国家代表的字符不⼀样;例如法语中130代表é,但是在希腊语中代表的是ג。
注意由于各个国家都是在美国制定的标准上来扩充ASCII 的,他们都保留了美国⼈制定的标准,也就是说所有的字符编码中,0-127表⽰的符号是⼀样的,128-256表⽰的符号在各个国家制定的编码表中是不⼀样的。
对于中⽂来说,256个字符根本不够⽤,常⽤的汉字就有5000多个,所以没有办法使⽤ASCII进⾏编码。
这时候为了统⼀编码,并且能够表⽰全世界所有的符号,就出现了Unicode编码。
unicode是⼀个标准,也可以说是世界上的语⾔字符和数字映射的⼀种标准。
它没有限制字符的数量,但是可能这个标准规定的映射只是映射了⼀部分字符。
⽹上说的Unicode编码占⼆个字节或者四个字节都是有问题的(⽬前来说,可能占两个字节(使⽤UCS-2),也可能占四个字节(使⽤UCS-4)关于UCS-2和UCS-4感兴趣可以了解⼀下)。
中文字符问题解决方案

中文字符问题解决方案中文字符问题是指在一些特定的环境下,处理中文字符出现乱码的情况。
解决这个问题的方法有以下几种:1. 使用正确的字符编码。
中文字符通常采用UTF-8编码,对于显示中文字符的场景,如网页、文档编辑器等,需要设置正确的字符编码,才能正确显示中文字符。
使用UTF-8编码可以保证兼容性和正确显示中文字符。
2. 修改文本文件的编码方式。
当我们打开一个文本文件,发现其中的中文字符显示为乱码时,可以尝试修改文件的编码方式来解决这个问题。
常见的文本文件编码方式有ANSI、UTF-8、UTF-16等,可以通过文本编辑器或专业的编码转换工具来修改文本文件的编码方式。
3. 修改数据库的字符编码。
当我们在数据库中存储和读取中文字符时出现乱码问题,可以尝试修改数据库的字符编码。
常见的数据库字符编码包括UTF-8、GBK、GB2312等,根据具体情况选择合适的字符编码,可以通过修改数据库配置文件、执行数据库命令等方式来修改数据库的字符编码。
4. 避免混合使用不同编码方式。
在一些场景下,可能会涉及到多个系统或工具之间的数据交互,为了避免中文字符出现乱码问题,需要确保所有涉及到中文字符的系统或工具使用相同的字符编码方式,避免混合使用不同编码方式导致的乱码问题。
5. 使用专业的中文字符处理工具。
针对中文字符问题,有一些专门的工具可以进行处理,例如编码转换工具、乱码检测工具等。
这些工具可以帮助我们识别和解决中文字符乱码的问题,提高处理效率和准确性。
总的来说,解决中文字符问题需要根据具体情况采取相应的解决方案,包括设置正确的字符编码、修改文本文件或数据库的编码方式,避免混合使用不同编码方式等。
同时,借助专业的中文字符处理工具可以提高解决问题的效率和准确性。
字符编码及乱码原理讲解

字符,字节和编码[原创文章,转载请保留或注明出处:/zh/encoding.htm]级别:中级摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。
举例说明了一些实际应用中,编码的实现方法。
然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。
本文的内容涵盖了“中文问题”,“乱码问题”。
掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。
因此,阅读本文时需要慢读多想,多思考。
引言“字符与编码”是一个被经常讨论的话题。
即使这样,时常出现的乱码仍然困扰着大家。
虽然我们有很多的办法可以用来消除乱码,但我们并不一定理解这些办法的内在原理。
而有的乱码产生的原因,实际上由于底层代码本身有问题所导致的。
因此,不仅是初学者会对字符编码感到模糊,有的底层开发人员同样对字符编码缺乏准确的理解。
回页首1. 编码问题的由来,相关概念的理解1.1 字符与编码的发展从计算机对多国语言的支持角度看,大致可以分为三个阶段:字符串在内存中的存放方法:在ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。
比如,"Bob123" 在内存中为:42 6F 62 31 32 33 00B o b 1 2 3 \0在使用ANSI 编码支持多种语言阶段,每个字符使用一个字节或多个字节来表示(MBCS),因此,这种方式存放的字符也被称作多字节字符。
比如,"中文123" 在中文Windows 95 内存中为7个字节,每个汉字占2个字节,每个英文和数字字符占1个字节:D6 D0 CE C4 31 32 33 00中文 1 2 3 \0在UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在UNICODE 字符集中的序号。
目前计算机一般使用2 个字节(16 位)来存放一个序号(DBCS),因此,这种方式存放的字符也被称作宽字节字符。
乱码形成原因及消除方法大全

览器却以编码B显示该网页,就会出现乱码,因此只要你在浏览器中也以编码A显示该网页,就会消除乱
码。
例如网页的代码中有形如:〈HTML〉〈HEAD〉〈META CONTENT=“text/html;charset=ISO-8859-1
”〉〈/HEAD〉的语句,浏览器在显示此页时,就会出现乱码,因为浏览器会将此页语种辨认为“欧洲语
乱码形成原因及消除方法大全 分类:IT技巧2006.2.13 14:47 作者:yajinfeng | 评论:4 | 阅读:20393
乱码形成原因及消除方法大全
当我们浏览网页、打开文档或邮件,运行软件时,经常会看到乱码,通常是由于源文件编码,Windows不
能正确识别造成的的,也可能是其他原因。乱码给我们带来了太多的烦恼,为了帮助大家彻底摆脱乱码
"assocSystemFont"="simsun.ttf"
"FontPackageDontCare"="宋体"
"FontPackageRoman"="宋体"
"FontPackageSwiss"="宋体"
"FontPackageModem"="宋体"
行文件.exe或压缩文件.zip等二进制文件)时,邮件服务器有可能无法处理,便把信件中每个字符的第
八位都过滤掉,从而造成邮件信息的失真或损坏,在收到邮件时就是一堆乱码。
体中文系统下,或者相反的情况,就会造成文档显示时乱码。只要你内码转换正确,例如把原本是繁体
的内码,转换为简体内码(或者相反),即可消除乱码。
Oracle字符集乱码问题

Alter system set job_queue_process=0;
Alter database open;
Alter database character set zhs16gbk;
客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件
字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。
若出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’ 这样的提示信息,
要解决这个问题有两种方法
1. 利用INTERNAL_USE 关键字修改区域设置,
2. 利用re-create,但是re-create有点复杂,所以请用internal_use
怎么查看数据库版本
select * from v$version 包含版本信息,核心版本信息,位数信息(32位或64位)等 至于位数信息,在Linux/unix平台上,可以通过file查看,如file $ORACLE_HOME/bin/oracle
二、. 查看数据库字符集
数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。
SQL>SHUTDOWN IMMEDIATE;
数据库中乱码问题解决方案

数据库中乱码问题解决方案数据库中乱码问题是一个常见的问题,特别是在多语言环境下。
在这种情况下,有时候我们会发现数据库中存储的数据出现乱码,这可能导致数据的有效性受到影响。
以下是一些解决方案,可以帮助您解决这个问题。
1. 确认数据库的字符集在创建数据库的时候,需要确认数据库的字符集是否正确。
如果字符集不正确,那么在存储数据的时候就会出现乱码问题。
可以通过以下查询语句来查看数据库的字符集:SHOW VARIABLES LIKE 'character_set_database';如果发现字符集有误,可以通过以下语句来修改数据库的字符集:ALTER DATABASE database_name CHARACTER SET utf8;2. 确认连接字符集连接字符集也可能导致乱码问题。
如果您的连接字符集与数据库字符集不同,那么在查询数据时就会出现乱码问题。
可以通过以下语句来查询连接字符集:SHOW VARIABLES LIKE 'character_set_connection';如果连接字符集有误,可以通过以下语句来修改连接字符集:SET NAMES utf8;3. 确认表的字符集在创建表的时候,需要确认表的字符集是否正确。
如果表的字符集不正确,那么在存储数据的时候就会出现乱码问题。
可以通过以下语句来查询表的字符集:SHOW CREATE TABLE table_name;如果发现字符集有误,可以通过以下语句来修改表的字符集:ALTER TABLE table_name CONVERT TO CHARACTER SET utf8;4. 确认字段的字符集在创建字段的时候,需要确认字段的字符集是否正确。
如果字段的字符集不正确,那么在存储数据的时候就会出现乱码问题。
可以通过以下语句来查询字段的字符集:SHOW FULL COLUMNS FROM table_name;如果发现字符集有误,可以通过以下语句来修改字段的字符集:ALTER TABLE table_name MODIFY column_name varchar(255) CHARACTER SET utf8;5. 确认应用程序的字符集除了数据库和连接字符集之外,应用程序的字符集也需要与数据库的字符集相同。
Java Web项目开发中的中文乱码问题与对策

Java Web项目开发中的中文乱码问题与对策在Java Web项目开发过程中,中文乱码问题是一个常见的挑战。
乱码问题通常发生在将中文数据存储到数据库、从数据库读取中文数据、在页面上展示中文数据等环节,如果不正确处理乱码问题,会导致用户无法正常阅读中文内容,影响用户体验。
下面介绍一些常见的中文乱码问题和对策。
1. 数据库乱码:当将中文数据存储到数据库中时,如果数据库的字符集不是UTF-8,会导致乱码问题。
解决方法是将数据库字符集设置为UTF-8,确保中文数据能够正确存储和读取。
2. 请求参数乱码:当用户提交包含中文字符的表单时,请求参数中的中文字符可能会出现乱码问题。
解决方法是在服务器端统一设置请求参数的编码为UTF-8,可以通过在web.xml文件中添加如下配置实现:```xml<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-c lass><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>``````html<meta charset="UTF-8">```4. 文件编码乱码:如果在Java Web项目中读取外部的文本文件,文件的编码可能与项目编码不一致,导致读取中文内容乱码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
关于字符集和乱码的思考关于字符集和乱码的思考2011-12-12 16:05:58分类:Delphi重要提示:本文并非学术文章,本人也并非语言和文字学领域人士,只是出于好奇心,根据自己的理解写下这篇文章。
本文的参考文档都来源于互联网,而且并未一一考证其准确性和权威性,因此本文仅供参考。
字符集和字符编码的问题一直困扰着我,之间曾经多次尝试把这个问题理解清楚,但始终由于有些细节问题无法自圆其说因而放弃。
网上的资料多数描述过于简单,又或者作者本人对问题也了解不深入,容易产生误导。
最近我终于下定决心将之前对“乱码”问题的思考更进一步,否则将始终是一丝遗憾。
这里也不得不感叹,老外的“科普”做的好啊,网上有很多质量相当高的文章,表述严密,引用充分,例证丰富,我相信在国内各领域的专家也不少,计算机和语言学方面都有很多有建树的大牛,也许是太忙吧。
对我个人而言,最重要的一片文章是“Character set encoding basics”,在本文最后有链接的地址,本人的翻译版本在这里:/space.php?uid=11187&do=b log&id=30344931.字符集的基本概念什么是字符集?什么是字符编码?按照“Character set encoding basics”文中的定义,字符集的编码模型分为以下4个层次1)抽象字符清单Abstract character repertoire (ACR),无序,无编码;2)已编码字符集Coded character set (CCS),有序,有编码;3)字符编码规则Character encoding form (CEF),有序,有编码;4)字符编码方案Character encoding scheme (CES),有序,有编码,有传输和储存规则(字节序);这种分层方式,比较偏于学术化,不太容易理解。
按我个人的理解,GB2312/GBK/GB18030/ASCII这些字符集编码规则,由于都基于8-bit字节,是属于前三层的,可以认为是三层合一。
如果拿Unicode来说明的话,Unicode中定义的所有字符的集合,是第一层;我们通常说的Unicode编码,是指的第二层;现在最常见的UTF-8,是指的第三层。
当UCS-4在以8-bit为基础的计算机中存储和传输时,就要涉及字节序的问题,就是第四层,分为big-endian和little-endian。
借用“程序员趣味读物:谈谈Unicode编码”中举的一个记事本例子(内容不同):1)打开记事本(windows自带的那个),输入“我”;2)另存为我_ansi.txt,注意,编码选择“ANSI”;3)另存为我_unicode.txt,注意,编码选择“Unicode”;4)另存为我_unicode_big.txt,注意,编码选择“Unicode Big Endian”;5)另存为我_utf8.txt,注意,编码选择“UTF-8”;保存完以后,看一下4个文件的大小,很有意思吧,分别是2/4/4/6个字节,再用二进制方式(推荐使用ultraedit)查看一下其中的内容:(高位字节在前)1)ansi:CE D22)unicode:FF FE 11 623)unicode_big:FE FF 62 114)UTF-8:EF BB BF E6 88 91第一个文件,ansi,比较好解释,2字节,就是GB2312/GBK/GB18030编码,即简体中文windows的默认内码第二个文件,unicode,就是Unicode编码,“我”的编码是0x62 0x11,不过前面多了2字节的前导符,FF FE,表示为little-endian第三个文件,unicode_big,也是Unicode编码,不过前导符变为FE FF,表示big-endian第四个文件,UTF-8,是在Unicode基础上的二次编码,分别将FE FF(big-endian)和62 11进行了二次编码,详细编码过程参见“程序员趣味读物:谈谈Unicode编码”常见字符集(字符编码规则)ASCII,读作阿斯克码,7bit表示,美国国家标准信息编码,是最常用英文字母和符号、数字的集合及编码;它的常见别名是ISO 8859-1 ,Latin1EASCII,扩展ASCII码,完整的利用一个字节,在ASCII的基础上扩展了一些不常用字符GB2312,国标中文字符编码,1980年制定并颁布;GBK,国标码,1995年GB18030,国标码,2000年以上这三个编码标准都是向下兼容的,兼容的意思有两方面,其一是指字符的集合,其二是指编码。
另外,在微软操作系统中(其实也影响到了Linux领域),经常出现“代码页”(code page)的概念,这些代码页,只是微软自己的定义,可以理解为CP936=GBK。
Unicode,UTF-8,我原来一直以为这两个东东是一回事,后来发现其实理解错了,UTF-8可以理解为是以Unicode为基础进行二次编码的,详见这篇文章:“程序员趣味读物:谈谈Unicode编码”,/empolder/gj/other/0505/6166 31_1.html2.关于乱码的思考什么是乱码个人认为,如果在储存或传输过程中,计算机中的信息不能被正常解析,从而导致在信息展示的时候出现无法被正确理解的情况,可以认为出现了“乱码”。
常见的乱码有两种表现形式:1)部分中文字符能够正常展示,另外的中文字符被展示为方框;这种情况多数是由于缺少相应的字体支持,例如,在虚拟机上安装完linux之后,如果没有安装图形界面,默认的字符窗口其实是没有相应的字体支持的,这时的中文只能显示为方框,安装zhcon以后才能够正常展示GBK/UTF8的中文字符。
还有一个场景,部分网页上的字符,并不能被所有浏览器支持,或者该浏览器对某种编码方式的支持不完整,会出现部分字符展示为方框的情况。
另外,如果能够以GBK/GB2312正常展示的网页,如果手工将encoding变更为utf-8,则所有中文字符都会变成方框。
2)几乎所有字符都不能正常展示,许多字符被显示为“?”,或者被显示为一大堆不可理解的古怪字符;这种情况很可能是由于字符编码不配套,需要具体分析。
例如,在浏览器中能够正常显示的页面,如果将其编码更改为其他不兼容的编码,则很多会展示为“?”和乱七八糟字符的组合乱码产生的原因产生乱码的原因很复杂,也正是这个原因导致了对乱码问题的分析很难全面和彻底。
但是,综合我目前遇到的乱码问题来看,只要将字符展示的过程剖析清楚,一段段的调整,总能找到解决的办法。
字符在计算机中,都是以二进制的方式进行存储的,而且文本本身是不能够标识它使用的编码方式的。
也就是说,同一段二进制字节流,可以用很多种不同的编码方式去解码,然后根据解码后的结果(也是二进制字节流),在操作系统中按照预定义好的字体进行展示。
所谓字体库,或者字库,其实就是数字和相应展示方式(点阵、truetype等)的组合。
计算机本身是不会“体会”到“乱码”的发生的,它只是按照用户选定的字体,根据不同的数字进行展示而已,无论展示的结果如何,都只有人才能判断“乱码”与否。
乱码的产生,其实只有两个原因,一是没有使用正确的解码规则来解释字节流,二是使用了错误的展示字体。
实际应用当中,编码规则的问题居多。
单字节的编码通常情况下不会出现乱码的问题,特别是英文字符,而双字节由于多数情况下编码规则复杂,另外存在中间截断的问题,会比较复杂。
从产生问题的渠道来看,常见的有以下几类:1)网页展示乱码多数情况下,可以通过更改页面编码方式来解决。
少数情况下,浏览器本身处理多语言字符集有缺陷的时候,无论怎样修改编码方式,都不能彻底解决乱码问题。
例如,截至本文定稿,IE9就存在部分UTF-8中文编码无法解析的问题,同样的网页在Chrome和firefox中都没有问题。
2)UNIX/LINUX终端显示乱码2.1)终端的中文环境;如果没有合适的中文环境(字库支持),无论解码方式如何正确,也不可能正常展示中文。
在常用的终端工具中,例如:Xshell/Secure CRT/Putty,都可以设置终端的字符编解码方式,通常设置的值有两个系列:其一,GB2312/GBK/GB18030/CP936/ANSI/Default等,其实都是兼容的编码,或者仅仅是名称不一样;其二,UTF-8,这个是在互联网上最常见的编解码方式了;另外,如果不是windows下的终端工具,而是系统自身的字符终端,则可以安装字符终端专用的中文环境,例如linux下的zhcon2.2)cat显示文本文档内容通过类似cat命令的方式显示纯文本文档的内容,通常只受一个因素的影响,即终端的工具的字符编码方式,常用工具中都可以进行设置。
只要文本内容的编码方式与终端的编码方式一致(或兼容),则一定不会出现乱码。
2.3)命令行的中文提示(CLI)命令行接口Command Line Interface的提示语言,是通过环境变量进行设置的,好几个变量都可以设置,但优先级有区别,其中LC_ALL > LC_XX > LANG,如果想用中文显示提示信息,可以这样设置:export LC_ALL=zh_CN.gbk其中zh表示使用中文输出提示信息,gbk表示使用GBK 编码方式输出中文提示信息,这个编码方式要与终端的设置一致或者兼容才可以正常显示;2.4)输入中文信息从Shell环境输入中文,与vi/vim这种编辑器的情况稍有不同,编辑器的情况放到下一节说明。
按照一般的理解(我原来就是这样理解的),只要能正常显示中文的地方,一定能够正常输入中文。
但是,实测的情况略有不同,详见下面的表格。
输入中文信息,我暂时只考虑了以下三种情况:a)在SHELL命令行中输入中文这种场景下,如果终端字符集是GBK,LC_ALL 为UTF-8时,输入的中文字节流乱序(第一个中文字符的高字节被放到字节流的末尾),无法正常展示。
b)使用cat等方式输入中文,并重定向到文件中这种场景下,任何时候,都能够正常输入中文c)使用文本编辑器,详见下一节描述与仅仅显示中文信息不同,输入中文的时候实际上经历了更多的步骤。
最开始从终端工具中输入中文编码字节流,然后经过网络协议传输到服务端,服务端收到字节流以后,根据终端设置的情况,再推送显示信息到终端工具,终端工具进行呈现。
在SHELL命令行中输入中文不正常的情况,很有可能是由于服务端的处理逻辑不健全。
2.5)文本编辑器,例如vim文本编辑器的种类很多,emacs/vi等,vi的版本也很多,各个主流UNIX平台的商业版本实现都不相同,还有vim。