编程语言
首页 > 编程语言> > 如何解决c++文件读写流无法读取中文的问题(vc6.0)

如何解决c++文件读写流无法读取中文的问题(vc6.0)

作者:互联网

代码

#include <iostream>
#include <fstream>
#include <locale>

using namespace std;

int main()
{
	setlocale(LC_ALL, "chs");	// 设置字符编码环境
	char buf;
	int x;
	wchar_t y, temp;
	ifstream is("D:\\存档\\OneDrive\\桌面\\作业\\测试文档.docx", ios::in);
	while(is.eof() == false)
	{

		is.read(&buf,sizeof(buf));
		if(int(buf) < 0)
		{
			y = 0x0000;
			y = buf;	// 取第一个字节的后4位
			y <<= 6;	// 为下一个字节的六位准备空间 
			is.read(&buf,sizeof(buf));
			// 取第二个字节的后六位
			temp = buf;
			temp = temp & (63);	// 取出temp的后六位
			y |= temp;
			y <<= 6;	// 为下一个字节的六位准备空间
			is.read(&buf, sizeof(buf));
			temp = buf;
			temp = temp & (63);
			y |= temp;

			printf("%S", &y);
			continue;
		}
		else
		{
			y = buf;
			printf("%s", &y);
		}
	}
	cout << endl;
	is.close();

	return 0;
}

运行结果

在这里插入图片描述

原理解释

在解决这个问题之前,我们需要先熟悉一下utf-8编码,大多数人认为中文在utf-8编码
里只占两个字节,其实这么表述是有问题的,真正的utf-8编码中,中文占据三个字节,
只不过只有两个字节是用来表示是哪个汉字的而已,具体详见下面这位大佬的文章

大佬文章

在这里插入图片描述

从上面的文章和这张图可以知道,ascii 表里面有的字符用的是第一种一个字节的编码方式,
而汉字用的是第三种编码方式,所以如果文档中只包含字符和汉字这两种字符的话,只需要
分类处理这两种情况就行了,而从图中可以发现中文编码和其他字符的不同之处:
	其他编码(只包含ascii里的字符)的字节都是以0开头的
	中文编码的三个字节都是从1开始的
所以,先将一个字节的内容读出来,之后将这个字节强转成为有符号数 int 类型,那么就会
出现所有的中文字符都是负数,所有的非中文字符都是正数,所以,对于强转之后是正数的
情况,直接输出就可以了,对于强转之后是负数的情况,就读取三个字节,之后将1号字节的
后四位取出来,2号字节的后六位取出来,3号字节的后六位取出来,并且将这些取出来的
二进制位重新拼接成为一个16位的字符,之后输出的就是汉字了,如果想要将汉字重新写回
文档并且不发生乱码的话,只需要将是汉字的部分重新构造成上面图中的三个字节编码的格式
写回文档就可以了

另外

这份代码里面的第一行代码是用来设置字符编码环境的
wchar_t 是宽字符,占据16位二进制位,定义原型是 typedef short wchar_t;
sprintf(%S, ..) 中的大S是专门用来输出宽字符的输出格式,这个格式必须在设置完编码格式之后才有效
c++的移位运算是算数移位
10进制的63是 0011 1111,只是c++里面不允许直接使用二进制值,所以我将这串二进制转换成为了十进制

标签:编码,中文,字节,vc6.0,字符,读写,c++,汉字,buf
来源: https://blog.csdn.net/qq_45760401/article/details/118466400