当前位置: 首页 > article >正文

fopen/fwrite/fread 对UNICODE字符写入的总结

windows对fopen函数进行了升级,可以支持指定文件的编码格式(ccs参数指定)。

例如:

FILE *fp = fopen("newfile.txt", "rt+, ccs=UTF-8");

当以 ccs 模式打开文件时,进行读写操作的数据应为 UTF-16 编码,存储为 wchar_t 类型。这意味着你应使用如 fgetwsfputws 等宽字符版本的函数进行读写,或者使用fread/fwrite读取和写入wchar_t 类型数据。

  • 我们下面来编写一个例子,文件编码格式指定为UTF-8,写入字符串带中文和英文,代码如下:
#include <stdafx.h>
#include <stdio.h>
void main()
{
	FILE *g_LogFile = fopen("D:\\UTF8.log", "w,ccs=UTF-8");
	int num = 10;
	while (--num > 0)
	{
        //用fputws和fwrite能得到相同的效果
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
 
		wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		fwrite(szLog, 2, wcslen(szLog), g_LogFile);
	}
	fclose(g_LogFile);
}

执行完上面代码,我们可以得到一个文件,用记事本打开文件如下:

然后用WinHex打开文件查看一下每个字节的数据如下:

从截图可知,确实是将Unicode字符集转成了UTF-8编码格式的字符集,然后写入了文件。

UTF-8编码格式的文件前面有3个字节的文件头。

  • 我们下面来编写另外一个例子,文件编码格UNICODE,写入字符串带中文和英文,代码如下:
#include <stdafx.h>
#include <stdio.h>
void main()
{
	FILE *g_LogFile = fopen("D:\\UNICODE.log", "w,ccs=UNICODE");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		//char szLog[1024] = "xiaoge is very good 我爱中国\n";
		//fwrite(szLog, 1, 19, g_LogFile);
	}
	fclose(g_LogFile);
}

上面代码执行结果如下,记事本打开:

WinHex打开:

从截图可知,写入文件的编码格式为UNICODE编码,UNICODE编码格式的文件前面有2个字节的文件头。

  • 当以 ccs 模式打开文件时,如果读写数据为char类型,则需要写入偶数字节,如果写入奇数字节,则会报错。

下面是写入奇数字节的代码:

#include <stdafx.h>
#include <stdio.h>
void main()
{
	FILE *g_LogFile = fopen("D:\\UNICODE.log", "w,ccs=UNICODE");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		//wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		//fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		char szLog[1024] = "xiaoge is very good 我爱中国\n";
		fwrite(szLog, 1, 19, g_LogFile);
	}
	fclose(g_LogFile);
}

执行上面代码会报错,报错如下:

如果我们将代码改为偶数字节,代码如下:

#include <stdafx.h>
#include <stdio.h>
void main()
{
	FILE *g_LogFile = fopen("D:\\UNICODE.log", "w,ccs=UNICODE");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		//wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		//fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		char szLog[1024] = "xiaoge is very good 我爱中国\n";
		fwrite(szLog, 1, 20, g_LogFile);
	}
	fclose(g_LogFile);
}

代码能执行成功,写入文件用记事本打开如下:

用WinHex打开如下:

从上面截图可知,数据确实成功写入了,文件也是UNICODE编码格式,但是写入的字符集不是UNICODE编码的,所以记事本打开会出现乱码。

从上面的代码执行结果确实验证了前面的结论:用css指定了文件的编码格式,读写数据的类型一定要用wchar_t类型,否则读写的数据是错误的。

  • 当不以 ccs 模式打开文件时,写入wchar_t类型数据,代码如下:
#include <stdafx.h>
#include <stdio.h>
void main()
{
	FILE *g_LogFile = fopen("D:\\ANSI.log", "w");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		//char szLog[1024] = "xiaoge is very good 我爱中国\n";
		//fwrite(szLog, 1, 20, g_LogFile);
	}
	fclose(g_LogFile);
}

执行上面代码,用记事本打开文件如下:

用WinHex打开文件如下:

从上面截图可知,文件编码格式为ANSI。由于编码格式和字节流对应不上,所以记事本显示乱码。

如果我们将写入的字节流改为char类型的数据,编码格式和字节流就能对应上,都为ANSI,此时文件显示也没问题。

  • 我们将写入文件的模式改为wb方式,文件编码格式将根据我们写入字节流的类型推断出来。

例如,我们用wb的模式写入wchar_t类型数据,代码如下:

#include <stdafx.h>
#include <iostream>
void main()
{
	FILE *g_LogFile = fopen("D:\\AUTO.log", "wb");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		//char szLog[1024] = "hunan bowan tech 湖南泊湾科技有限公司\n";
		//fwrite(szLog, 1, strlen(szLog), g_LogFile);
	}
	fclose(g_LogFile);
}

执行上面代码,用记事本打开文件如下:

如果我们用wb的模式写入char类型数据,代码如下:

#include <stdafx.h>
#include <iostream>
void main()
{
	FILE *g_LogFile = fopen("D:\\AUTO.log", "wb");
	int num = 10;
	while (--num > 0)
	{
		//fputws(L"hunan bowan tech 湖南泊湾科技有限公司\n", g_LogFile);
		//wchar_t szLog[1024] = L"hunan bowan tech 湖南泊湾科技有限公司\n";
		//fwrite(szLog, 2, wcslen(szLog), g_LogFile);

		char szLog[1024] = "hunan bowan tech 湖南泊湾科技有限公司\n";
		fwrite(szLog, 1, strlen(szLog), g_LogFile);
	}
	fclose(g_LogFile);
}

​

执行上面代码,用记事本打开文件如下:


综上所述可知:

如果用"w"的模式,写入wchar_t类型字节数据,最好通过ccs指定编码格式。

否则就用“wb”的模式写入。


http://www.kler.cn/a/133163.html

相关文章:

  • 【Linux:epoll】
  • Python学习从0到1 day26 第三阶段 Spark ④ 数据输出
  • Flutter:Widget生命周期
  • sql注入之二次注入(sqlilabs-less24)
  • 跨域请求解决的核心
  • Node.js GET/POST请求、WEB模块使用介绍 (基础介绍 八)
  • 【XTDrone Ubuntu20.04】XTDrone+ Ubuntu20.04 + PX4安装
  • 论文阅读:Auto White-Balance Correction for Mixed-Illuminant Scenes
  • SpringBoot学习笔记-创建个人中心页面(下)
  • 大数据-之LibrA数据库系统告警处理(ALM-12051 磁盘Inode使用率超过阈值)
  • MongoDB分片集群搭建
  • Axelar、J.P.Morgan Onyx、Apollo 完成概念验证,向跨区块链自动化投资领域探索
  • 手搓哈希表、列表、队列,只为了用C语言快速求解华容道游戏,我不是大佬,只是一个游戏算法爱好者
  • Alien Skin Exposure2024胶片滤镜中文免费版插件
  • C语言的由来与发展历程
  • 微信小程序开发-----发起网络请求携带后端token
  • Error message “error:0308010C:digital envelope routines::unsupported“
  • SpringBoot-过滤器Filter+JWT令牌实现登录验证
  • Vue.js2+Cesium1.103.0 十四、绘制视锥,并可实时调整视锥姿态
  • WPF自定义控件介绍
  • 【作业】操作系统实验一:进程和线程
  • 释放机器人潜力,INDEMIND深耕底层技术
  • JMeter-BeanShell预处理程序和BeanShell后置处理程序的应用
  • 目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】计算机视觉(补充篇)
  • 项目踩坑之面试遇到的问题及解决
  • 自动化网络图软件