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.mzph.cn/news/146947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Trino 与Hive 有差异的函数

日常使用中发现trino和hive中的有一些函数存在差异&#xff0c;所以开此帖记录一下 这里只是记录trino和hive有差异的函数&#xff0c;遇到了就会记录一下&#xff0c;不定期更新 1. 查看集合中元素个数 hive&#xff1a;size() trino&#xff1a;cardinality() 2. map取值 …

迭代器与生成器

章节目录&#xff1a; 一、迭代器1.1 相关概述1.2 基本使用1.3 自定义迭代器 二、生成器2.1 相关概述2.2 基本使用2.3 三种应用场景 三、yield 和 class 定义的迭代器对比四、结束语 一、迭代器 1.1 相关概述 迭代是 Python 最强大的功能之一&#xff0c;是访问集合元素的一种…

Selenium自动化测试框架

一.Selenium概述 1.1 什么是框架? 框架&#xff08;framework&#xff09;是一个框子——指其约束性&#xff0c;也是一个架子——指其支撑性。是一个基本概念上的 结构用于去解决或者处理复杂的问题。 框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及…

【Machine Learning in R - Next Generation • mlr3】

本篇主要介绍mlr3包的基本使用。 一个简单的机器学习流程在mlr3中可被分解为以下几个部分&#xff1a; 创建任务 比如回归、分裂、生存分析、降维、密度任务等等挑选学习器&#xff08;算法/模型&#xff09; 比如随机森林、决策树、SVM、KNN等等训练和预测 创建任务 本次示…

如何使用Java实现权限认证和登录jwt

这边可以关注我的博客 权限认证 轻松实现权限认证 登录拦截 轻松实现登录拦截 这样就可以了

C语言每日一题(32)环形链表

力扣网 141.环形链表 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾…

LLM大模型4位量化实战【GPTQ】

权重量化方面的最新进展使我们能够在消费类硬件上运行大量大型语言模型&#xff0c;例如 RTX 3090 GPU 上的 LLaMA-30B 模型。 这要归功于性能下降最小的新型 4 位量化技术&#xff0c;例如 GPTQ、GGML 和 NF4。 在上一篇文章中&#xff0c;我们介绍了简单的 8 位量化技术和出…

GZ038 物联网应用开发赛题第10套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第10套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考…

Spring学习③__Bean管理

目录 IOC接口ApplicationContext 详解IOC操作Bean管理基于xml方式基于xml方式创建对象基于xml方式注入属性使用set方法进行注入通过有参数的构造进行注入p 名称空间注入&#xff08;了解&#xff09; 基于xml方式注入其他类型属性xml 注入数组类型属性 IOC接口 IOC思想基于IOC…

Linux 无名管道实现文件复制

无名管道 通过一个管道&#xff08;假象&#xff09;进行传输数据&#xff0c;但是这个管道的传输方式是单工&#xff08;半双工&#xff09;的&#xff0c;就是这个管道允许进行发送和接受数据&#xff0c;不过不能同时进行。 创建无名管道 这里用到一个pipe&#xff08;&…

代码随想录算法训练营第三十九天【动态规划part02】 | 62.不同路径、63. 不同路径 II

62.不同路径 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 动规五部曲 确定dp数组及其下标含义&#xff1a;dp[i][j] 表示从&#xff08;0,0&#xff09;出发&#xff0c;到&#xff08;i,j&#x…

Ubuntu16.04系统在Docker容器搭建 Gitlab 服务器

Ubuntu16.04系统在Docker容器搭建 Gitlab 服务器 从Docker Hub下载最新版本的GitLab CE镜像到您的本地Docker环境中,根据您的网络连接速度和镜像大小,这个过程可能需要一些时间。当拉取完成后,您就可以使用该镜像来运行GitLab容器了 docker pull gitlab/gitlab-ce:latest如果…

性能测试【第三篇】Jmeter的使用

线程数:10 ,设置10个并发 Ramp-Up时间(秒):所有线程在多少时间内启动,如果设置5,那么每秒启动2个线程 循环次数:请求的重复次数,如果勾选"永远"将一直发送请求 持续时间时间:设置场景运行的时间 启动延迟:设置场景延迟启动时间 响应断言 响应断言模式匹配规则 包括…

AIGC创作系统ChatGPT源码,AI绘画源码,支持最新GPT-4-Turbo模型,支持DALL-E3文生图

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

无线WiFi安全渗透与攻防(五) mdk4安装(kali linux)以及更新kali源

无线WiFi安全渗透与攻防(五) mdk4安装(kali linux) 一. 2021最新版kali-2021-4a 更新源Kali 系统换源1.使用leafpad编辑器打开系统源文本(也可用vim)2.填写源文本(源文本无硬性要求,这里我用的是阿里的)3.使用更新源命令进行更新源4. 下载mdk4二. WIFI泛洪攻击-基于MDK4…

​软考-高级-系统架构设计师教程(清华第2版)【第7章 系统架构设计基础知识(263~285)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第7章 系统架构设计基础知识&#xff08;263~285&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

【完整详细】IntelliJ IDEA中使用Docker插件一键部署前后端分离项目

前言:在使用Docker部署我们的前后端分离项目的时候,会涉及到一堆且重复的Docker命令,久而久之就会被这些重复性的操作感到繁琐,本篇博客教学大家如何通过IDEA自带的一款插件就可以实现一键部署前后端分离项目的操作,从头到尾我写的非常详细,大家逐步阅读即可。 博主的其他…

LeetCode(18)整数转罗马数字【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 12. 整数转罗马数字 1.题目 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X …

原型网络Prototypical Network的python代码逐行解释,新手小白也可学会!!-----系列4

文章目录 原型网络进行分类的基本流程一、原始代码---计算欧氏距离&#xff0c;设计原型网络&#xff08;计算原型开始训练&#xff09;二、每一行代码的详细解释总结 原型网络进行分类的基本流程 利用原型网络进行分类&#xff0c;基本流程如下&#xff1a; 1.对于每一个样本…