C语言读取文本文件到字符数组中,和源文件文本长度不一致

今天我踩到了C语言的一个坑,导致我一个小时内都在找答案。
问题描述如下:
我想把本地文本文件通过C语言读取到unsigned char缓存数组中,供其他函数调用。
我采用
fopen函数只读文件,
fseek函数找到文本结尾,
ftell函数获取整个文本的长度,
rewind函数回滚指针到文本开头,
fread函数读取文件到缓存数组。
但是缓存数组的内容却和文本文件的内容不一致。
案例如下:
我的txt:
ABCDEFG
HIJKLMN
OPQRST

在这里插入图片描述
UTF-8格式。
文件属性如下:
在这里插入图片描述
26字节
20个字符,加3个换行符,3个回车符。 \n \r
注意:最后一行有换行符号。

程序:

#include <stdlib.h>
#include <stdio.h>
void main()
{
	FILE *fp;//定义文件流指针,用于打开读取的文件
	int len=0;
	unsigned char  test[1024*4];
	fp = fopen("test.txt","r");//只读方式打开文件
	fseek(fp, 0, SEEK_END);
	len = ftell(fp);
	rewind(fp);
	fread(test,1,len, fp);
	test[len]='\0';
	printf("%s\n",test);
	fclose(fp);//关闭文件,有打开就要有关闭
	system("pause");
}

ftell返回的len为26。20个字符,加3个换行符,3个回车符。 \n \r

结果如下:

在这里插入图片描述
是不是很奇怪?
单步调试显示缓存数组:
在这里插入图片描述
少了三个换行符。
原因如下:
问题应该出在了第二步fopen那里

fopen需要mode参数,即以什么模式打开文件;
默认情况下,使用ANSI格式;
使用UNICODE, UTF-8, 或 UTF-16LE等Unicode模式打开文件时,将会对读取到的内容进行转换成目标格式;也意味着转换后字节与原始字节很可能不一样;
读或写存储为UTF-8编码格式的数据时,可用文本模式或者二进制模式替代Unicode模式。

以unicode、t模式打开文件,会进行字节转换,转换后的字节数和原始字节数很可能不一样,如果要读取内容,要开启b(Open in binary)模式,

乱码是多余的垃圾值(初始化时赋的初始值)。ftell()返回值比fread()返回值大。fread返回实际得到的字符数,正常情况文本文件中\r\n读取后变成了\n,这就会导致读取的字符串小于实际文本文件中的长度。当用rb取代r时,即用二进制模式时,ftell()和fread()返回的值相同。

如果源文件是UTF-8编码的(其实不管什么编码格式文件),fopen时开启rb(read mode and open in binary)即可。

即:
fopen时开启rb(read mode and open in binary)即可读取原始内容,读到的字节数和原始字节数一致;
最新程序如下:

#include <stdlib.h>
#include <stdio.h>
void main()
{
	FILE *fp;//定义文件流指针,用于打开读取的文件
	int len=0;
	unsigned char  test[1024*4];
	fp = fopen("test.txt","rb");//只读方式打开文件
	fseek(fp, 0, SEEK_END);
	len = ftell(fp);
	rewind(fp);
	fread(test,1,len, fp);
	test[len]='\0';
	printf("%s\n",test);
	fclose(fp);//关闭文件,有打开就要有关闭
	system("pause");
}

ftell返回的len为26。20个字符,加3个换行符,3个回车符。
在这里插入图片描述
在这里插入图片描述
模式更改以后,回车符也读出来了,这才和ftell返回的字符数对的上。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值