读取文件中文乱码

void test_c()
{
	FILE *fp = fopen("F:\\example\\vs2010\\txt\\test2.txt","r+");  //若文件不存在时,fp为空
	if(fp == NULL)
	{
		perror("error");
		printf("%d\n",errno);    //错误号
	}
	else
	{
		char temp[1024] = {0};
		while(!feof(fp))
		{
			char *str = fgets(temp,1024,fp);
			if(str == NULL)
			{
				break;
			}
			printf("%s",temp);
		}
		fclose(fp);
	}
	return;
}

qt读取txt文件 

    QFile file("F:/example/vs2010/txt/test1.txt");
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
	    while(!file.atEnd())
	    {
		    QString str = file.readLine();
	    }
    }

//1111111浣犲ソ1111

//打开文件另存为,选择ANSL编码方式,就不会出现乱码

    QFile file("F:/example/vs2010/txt/test1.txt");
	if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		return;
	}
	QTextStream in(&file);
	//in.setCodec("gbk");
	QString s = in.readAll();

使用流的方式读取txt文件,在exe中in默认编码方式为gbk,读取ANSI编码方式文件不会乱码。
不设置编码方式时,读取utf-8编码格式的文件时显示乱码,执行in.setCodec("utf-8");后,正确解码。

qt写txt文件

    QFile file("F:/example/vs2010/txt/in1.txt");
	if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
	{
		return;
	}
	QTextStream in(&file);
	in.setCodec("gbk");
    //in.setCodec("utf-8");
	in <<  "1" << QString("你好");
	file.close();

不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、Big5、Shift_JIS 等各自的编码标准。这些使用 1 至 4 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 当然对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。这一点是ANSI编码与Unicode编码之间最大也最明显的区别。

ASCII

世界上虽然有各种各样的字符,但计算机发明之初没有考虑那么多,基本上只考虑了美国的需求。美国大概只需要128个字符,美国就规定了这128个字符的二进制表示方法,这个方法是一个标准,称为ASCII编码,全称是American Standard Code for Information Interchange( 美国信息互换标准代码) 。128个字符用7个位刚好可以表示,计算机存储的最小单位是byte,即8位,ASCII码中最高位设置为0,用剩下的7位表示字符( 即0-127 )。数字32到126表示的这些字符都是可打印字符,0到31和127表示一些不可以打印的字符,这些字符一般用于控制目的。

GB2312


GB2312是中文的第一个标准。主要针对简体中文常见字符 (包括约7000个汉字,不包括一些罕见词、繁体字)。GB2312固定使用两个字节表示汉字,在这两个字节中最高位都是1,如果是0则认为是ASCII字符。( 解码时若高位是0则只解码1个字节,否则解码连续2个字节 )
在这两个字节中,其中第一个字节范围是1010 0001(十进制161) - 1111 0111(十进制247),第二个字节范围是1010 0001(十进制161) - 1111 1110(十进制254)

GBK


GBK建立在GB2312的基础上且向下兼容GB2312。GBK在GB2312的基础上增加了一万四千多个汉字,共计约21000汉字,其中包括繁体字。
GBK使用固定的两个字节表示,其中第一个字节范围是1000 0001(十进制129) - 1111 1110(十进制254),第二个字节范围是0100 0000(十进制64) - 0111 1110(十进制126)和1000 0000(十进制128) - 1111 1110(十进制254)。

注:GBK第二个字节是从64开始的,也就是说第二个字节最高位可能为0。那怎么知道它是汉字的一部分,还是一个ASCII字符呢? 解决方案是:因为是固定2字节编码,所以若第1个字节的高位是1则直接连续解码2个字节,否则解码1个字节。

GB18030


GB18030向下兼容GBK,使用变长编码( 2字节或4字节 ) 。GB18030在GBK的基础上增加了五万五千多个字符,共七万六千多个字符。包括了很多少数民族字符,以及中日韩统一字符。
在两字节编码中,字节表示范围与GBK一样。在四字节编码中,第一个字节的值从1000 0001(十进制129) 到11111110(十进制254),第二个字节的值从0011 0000(十进制48)到00111001(十进制57),第三个字节的值从1000 0001(十进制129) 到11111110(十进制254),第四个字节的值从0011 0000(十进制48)到0011 1001(十进制57)

注: 解码时如何知道是两个字节还是四个字节表示一个字符呢?解决方案是:看第二个字节的范围,如果是48到57就是四个字节表示


Unicode

Unicode并不是一种编码方式,只是为每一个文字、符号分配了唯一的数字编号。编号范围从0x000000到0x10FFFF(0-1114111),Unicode编号写成16进制并在前面加U+。具体的编码方式有UTF-8、UTF-16、UTF-32

UTF-32

固定使用4个字节编码

  • 大端(LE)、小端(BE)
    大端:数据的高字节保存在内存的低地址中,低字节保存到内存的高地址中
    小端:数据的低字节保存在内存的高地址中,高字节保存到内存的低地址中
    大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理

UTF-16

基本平面的字符占用 2 个字节,辅助平面的字符占用 4 个字节。也就是说,UTF-16 的编码长度要么是 2 个字节(U+0000 —— U+FFFF),要么是 4 个字节(U+010000 ——U+10FFFF)

UTF-8

UTF-8使用变长字节(字节个数从1到4个不等),每个字符使用的字节个数与其Unicode编号的大小有关

utf-8编码:字母,数字占用一个字节;汉字占三个字节

编码方式:

读取文件中文乱码_第1张图片

  • 以上编码方式除了UTF-16、UTF-32不兼容ASKII外,其余都兼容
  • 对于纯汉字的编码,GBK优于UTF-8。因为大多数汉字在UTF-8编码中占用3字节,但是GBK固定占用2字节。所以在传输时速度更快

你可能感兴趣的:(c++,数据结构,c语言)