流操作之读写(fread、fwrite、fopen、malloc)

本文详细介绍使用fread和fwrite函数实现文件从“source.c”到“dst.c”的复制过程,包括文件打开、内存分配、读写操作及错误处理等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fgets、fread函数

fwritre函数

文件结束函数

错误指示函数

#include<stdio.h>

#include<stdlib.h>

int main(int arge,char **argv)

{

           int ret=-1;
        //拷贝 源文件(source.c)到目标文件(dst.c)
        FILE *fp_s=NULL;//源文件流
        fp_s=fopen("source.c","r");//只读该文件 r
        if(NULL==fp_s)

        {
        perror("fopen source.c");
        return -1;
        }



        //目的文件
        FILE *fp_d=NULL;//目标文件流
        fp_d=fopen("dst.c","w");
        if(fp_d==NULL)
        {
        perror("fopen dst.c");
        return -1;
        }
        //准备内存
        char *buff=NULL;
        buff=malloc(20);//堆 20个字节
        if(NULL==buff){
         perror("malloc buff");
         return -1;
        }
        //读
        //文件,内存地址,读多少内容
        //给读函数提供的信息:读的文件的名称,读到那去,读多少,从哪里开始读。
         //从源文件的默认光标(文件位置处)
        //存放到用户内存里面

    while(1)
    {
        ret= fread(buff,1,20,fp_s);
        if(20>ret)
        {
          //读到source.c文件的尾部
          if(feof(fp_s))
          {
           ret=fwrite(buff,1,ret,fp_d);
           if(0==ret)
           {
            perror("fwrite");
            return -1;
           }
           break;
          }else{
           //出错
           perror("fread");
           return -1;
          }
        }
        //写
        ret=fwrite(buff,1,ret,fp_d);
        if(0==ret){
        perror("fwrite");
        return -1;
        }


     }
        free(buff);
        buff=NULL;
        fclose(fp_d);
        fp_d=NULL;
        fclose(fp_s);
        fp_s=NULL;
return 1;
}


详解这个函数的返回值:

RETURN VALUE
 fread()  and  fwrite()  

return  the  number of items successfully read or written (i.e., not the number of characters). 

      If an error occurs, or the end-of-file is reached, the return value is ashort item count (or zero).

如果成功返回就是item,如果错误返回就是short item,如果end-of-file就返回zero。

The  function  feof()

tests the end-of-file indicator for the stream pointed to by stream, returning non-zero if it is set.  The end-of-file indicator can only be cleared by the function clear- err().

The function ferror() 

tests the error indicator for the stream pointed to by stream, returning non-zero if it is set.  The error indicator can only be reset by the clearerr() function.


fread函数的返回值就三种:item,short item,zero。不是item这种情况,就是short item和zero这两种情况,

 ret= fread(buff,1,20,fp_s);
        if(20>ret)
        {
          //读到source.c文件的尾部
          if(feof(fp_s))
          {
           ret=fwrite(buff,1,ret,fp_d);
           if(0==ret)
           {
            perror("fwrite");
            return -1;
           }
           break;
          }else{
           //出错
           perror("fread");
           return -1;
          }
        }

执行程序:

gcc mycopy.c -g

./a.out

gdb a.out

b main(在main函数处设置断点)

r运行

n

n

p fp_s(显示)

p fp_d

s

p buff


总结:

第一步:打开文件(fopen)

 FILE *fp_s=NULL;//源文件流
fp_s=fopen("source.c","r");//只读该文件 r

第二步:准备内存空间

  buff=malloc(20);//堆 20个字节

第三步:

进行读写操作。

ret=fwrite(buff,1,ret,fp_d);

ret= fread(buff,1,20,fp_s);

第四步:关闭数据流,释放内存


第一是:逻辑思维(有计算机执行决定)

第二是:需要用到的函数(熟悉函数的用法)







### 使用 `fwrite` 和 `fread` 进行文件读写 #### 函数原型说明 `fwrite()` 和 `fread()` 是用于二进制文件操作的标准库函数。这两个函数能够高效地处理大量数据,特别适合于二进制文件操作。 - **fwrite**: 向指定文件中写入若干数据块,如果成功执行,则返回实际写入的数据块数目[^2]。 ```c size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); ``` - **fread**: 从指定文件读取若干数据块,成功时返回实际读取到的数据块数目. ```c size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); ``` 参数解释: - `ptr`: 数据缓冲区地址指针; - `size`: 单个元素的字节数; - `nmemb`: 元素数量; - `stream`: 文件对象; #### 示例代码展示 下面是一个完整的例子来演示如何利用 `fwrite` 和 `fread` 来保存和恢复结构体数组至文件: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int id; char name[50]; } Student; int main(){ // 创建并初始化学生记录 Student students[] = {{1,"Alice"}, {2,"Bob"}}; const int numStudents = sizeof(students)/sizeof(Student); // 打开文件准备写入 FILE* fpWrite = fopen("students.dat", "wb"); if (fpWrite == NULL){ perror("无法打开文件进行写入"); exit(EXIT_FAILURE); } // 将内存中的数据写入文件 size_t result_write = fwrite(students, sizeof(Student), numStudents, fpWrite); fclose(fpWrite); printf("已写入 %zu 名学生的记录\n",result_write); // 打开文件准备读取 FILE* fpRead = fopen("students.dat","rb"); if (fpRead==NULL){ perror("无法打开文件进行读取"); exit(EXIT_FAILURE); } // 动态分配空间存储读回的学生信息 Student* read_students=(Student*)malloc(numStudents*sizeof(Student)); if (!read_students){ puts("内存不足!"); fclose(fpRead); exit(EXIT_FAILURE); } // 从文件读取数据到内存 size_t result_read=fread(read_students,sizeof(Student),numStudents,fpRead); fclose(fpRead); printf("已读取 %zu 名学生的记录\n",result_read); // 输出读取的内容验证正确性 for(int i=0;i<result_read;++i){ printf("ID:%d Name:%s\n",read_students[i].id,read_students[i].name); } free(read_students); } ``` 此程序先创建了一个包含两个学生的信息列表,并将其序列化后存入名为 `"students.dat"` 的文件中。之后再次打开这个文件并将其中的数据反序列化回到新的变量里显示出来以确认读取无误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值