IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 如何解决c++文件读写流无法读取中文的问题(vc6.0) -> 正文阅读

[C++知识库]如何解决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++里面不允许直接使用二进制值,所以我将这串二进制转换成为了十进制
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-05 20:18:22  更:2021-07-05 20:18:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 4:45:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码