在C语言中文件操作有许多函数,open、fopen、freopen等,这次“传统”的fopen
最近在学习C语言的Socket的使用,在读取数据时遇到了两个问题
首先是文件的读取问题
读取文件名为1.txt的前1024个字节:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char buf[1024];
FILE* fp;
fp = fopen("1.txt", "rb");
fread(buf, sizeof(char), 1024, fp);
cout << buf;
}
运行结果如下,尾部出现乱码
查询得知,cout会读到‘\0‘标记,而fread函数读取数据后没有在末尾加上\0,导致读到了buf外面的\0才停下。
于是使用memset函数,将buf初始化全部填充成0:
memset(buf, 0, sizeof(buf));
运行一下,结果还是有乱码
这个问题我最初以为是memset没有初始化成功,在经过几次测试后得到了结果
fread读取1024字节后正好占满了buf,所以应该在buf的后面加上\0,故应该改成
memset(buf, 0, sizeof(buf)+1);
问题顺利解决,只是VS报错buf后面的块被破坏,把buf开大一些存储\0即可解决
至此,读取文件看起来是正常了,但是在我尝试读入一张图片时,发现没能读取完整块数据
这个问题是我在写好了socket发包时接收文件发现文件大小与发送的不一致,经过检查,与网络相关的模块没有问题,问题还是出现在读写文件上
读文件最好使用二进制类型(rb)读取,可以避免一些控制字符带来的问题
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
char buf[1024];
FILE* fp;
fp = fopen("C:\\Users\\lyl\\Desktop\\QQ图片20200521221322.png", "rb");
cout<<"本次读取了 "<<fread(buf, sizeof(char), 1024, fp)<<endl;
cout<<"buf的实际长度 "<<strlen(buf);
}
运行结果:
strlen求长也是遇到’\0’就停下来,可能是读取的数据中有0导致
按int把buf输出 果然a[8]是0
所以在对于fread获取的数据,最好不要用strlen求读出的长度,直接用fread的返回值即可。