C语言文件读写


创建一个文件指针

FILE *fp=fopen(“文件路径”,“打开模式”);

其中打开模式有:

r (read): 只读
w (write): 只写
a (append): 追加
t (text): 文本文件(默认),可省略不写
b (binary):二进制文件
+: 读和写


读取文件(read)
fread()

声明:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

参数:

ptr : 指向带有最小尺寸 size*nmemb 字节的内存块的指针。用来指定读取的文件数据存放的区域
size :要读取的每个数据块的大小,以字节为单位。
nmemb : 数据块的个数,每个数据块的大小为 size 字节。
stream – 这是指向 FILE 对象的指针,该 FILE对象指定了一个输入流。

这里附上使用fread函数读取二进制文件的代码

inline size_t readBinaryFile(const char * filename,unsigned char * data)
{
    FILE* fp;
    fopen_s(&fp,filename, "rb");
    if (fp == NULL) return 0;  //空指针则返回0,文件打开失败
    fseek(fp, 0, SEEK_END);
    size_t size = ftell(fp);  //计算文件大小,单位:Byte
    fseek(fp, 0, SEEK_SET);
    data = (unsigned char *)malloc(sizeof(unsigned char)*size);
    fread(data,size,1,fp);
    fclose(fp);
    return size;
}

这里利用fseek函数将文件指针指向文件末尾,再用ftell函数来获取文件大小size
该函数返回值为读取的文件的大小,单位是byte(字节)

注意如果读取的不是二进制文件而是文本文件,那么应在data数组的末尾补上:

data[size] = '\0';

否则输出文本内容的时候没有字符串结束符将会引发错误。

上述函数还有一个潜在的问题,如果读取的文件大小超过了size_t的表示范围(也就是data数组的长度超过了系统允许的最大数组长度),就应先将文件数据划分为几段,分别读入不同的数组。

关于size_t的作用,可以参考这篇文章:为什么size_t重要?(Why size_t matters)
简言之,size_t表示的数据范围是当前平台地址总线的宽度,也就是你所能声明的最大数组长度


fwrite()

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

ptr – 指向要被写入的元素数组的指针。
size – 被写入的每个数据块的大小,以Byte(字节)为单位。
nmemb – 将要写入的数据块的个数,每个数据块的大小为 size 字节。
stream – 指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。

下面同样给出了一个fwrite进行二进制写入的函数。

inline size_t writeBinaryFile(const char* filename, unsigned char* data, size_t size)  //size:要写入的数据大小(单位:字节)
{
    FILE* fp;
    fopen_s(&fp,filename, "wb");
    if (fp == NULL) return 0;
    size_t written_size= fwrite(data, size, 1 ,fp);
    fclose(fp);
    return written_size;
}


fscanf()

声明:

int fscanf(FILE *stream, const char *format, )

参数:

stream : 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
format : 这是 C
字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。 format 说明符形式为
[=%[*][width][modifiers]type=],以下是百度百科的描述:

参数描述
*这是一个可选的星号,表示数据是从流 stream 中读取的,但是可以被忽视,即它不存储在对应的参数中。
width这指定了在当前读取操作中读取的最大字符数。
modifiers为对应的附加参数所指向的数据指定一个不同于整型(针对 d、i 和 n)、无符号整型(针对 o、u 和 x)或浮点型(针对 e、f 和 g)的大小: h :短整型(针对 d、i 和 n),或无符号短整型(针对 o、u 和 x) l :长整型(针对 d、i 和 n),或无符号长整型(针对 o、u 和 x),或双精度型(针对 e、f 和 g) L :长双精度型(针对 e、f 和 g)
type一个字符,指定了要被读取的数据类型以及数据读取方式。具体参见下一个表格。

  

可以把 fscanf 看成是自行设定文件流的 scanf 函数
比如下面两条语句的效果是完全一致的:

fscanf(stdin,"%d",&n);
scanf("%d",&n);

通过重定向标准输入/输出实现文件读写:
freopen()

FILE * freopen ( const char * filename, const char * mode, FILE * stream );

比如现在我们需要在data.in中读取数据,在data.out中写入数据:

freopen("data.in","r",stdin);
freopen("data.out","w",stdout);

然后使用scanfprintf等原本从控制台读取和输出的函数时,都会被重定向到指定文件中
最后别忘了关闭文件流:

fclose(stdin);
fclose(stdout);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值