标准IO详解(fgets、gets、fread、fwrite、fseek 等应用)
1.fwrite
核心逻辑:
定义结构体 Student
:包含学生的学号 id
、姓名 name
(长度32字节)、分数 score
。
打开文件(./1.txt
,以写模式 "w"
):创建或清空该文件,准备写入数据。
初始化5个学生信息的数组 stu
。
调用 fwrite
:将数组 stu
中的5个结构体元素,以二进制形式写入文件。
参数说明:
stu
:数据起始地址
sizeof(Student)
:每个结构体大小
5
:写入5个元素
fp
:文件指针
打印实际写入的元素数 counter
,用于确认写入成功。
关闭文件流。
int main()
{typedef struct student{int id;char name[32];int scroe;}Student;FILE *fp = fopen("./1.txt","w");if(NULL == fp){printf("fopen error\n");return -1;}Student stu[5] = {{1,"zhangsan",90},{2,"lisi",34},{3,"wangfu",89},{4,"maliu",87},{5,"zhaoliu",99}};size_t counter = fwrite(stu, sizeof(Student), 5, fp);printf("counter = %ld\n",counter);fclose(fp);return 0;
}
2.fread
核心逻辑:
定义结构体 Student
,与写入时的结构相同,包含学生 id
、name
和 score
。
打开文件(./1.txt
,以读模式 "r"
):
准备从文件中读取二进制数据。
定义数组 stu[10]
,用于存放最多读取的10个学生结构体。
调用 fread
:
从文件中读取最多10个 Student
结构体大小的数据块,存入数组 stu
。
返回实际读取的结构体个数 counter
。
打印读取到的元素数量 counter
。
循环遍历 stu
数组中的有效数据(0
到 counter-1
),逐个打印学生的 id
、name
和 score
。
关闭文件。
int main()
{typedef struct student {int id;char name[32];int scroe;}Student;FILE *fp = fopen("./1.txt","r");if(NULL == fp){printf("fopen error\n");return -1;}Student stu[10];size_t counter = fread(stu, sizeof(Student), 10, fp);printf("%ld\n",counter);int i;for(i = 0;i < counter;++i){printf("%d %s %d\n",stu[i].id,stu[i].name,stu[i].scroe);}fclose(fp);return 0;
}
3.fseek
核心逻辑:
打开文件 ./1.txt
,以写模式 ("w"
),如果打开失败,打印错误并退出。
使用 fseek(fp, 11, SEEK_SET)
:
将文件指针移动到文件开头向后偏移11个字节的位置。
调用 fputc('A', fp)
:
在当前位置写入字符 'A'
。
调用 fseek(fp, -3, SEEK_CUR)
:
在当前位置基础上向前移动3个字节。
调用 fputc('B', fp)
:
在新的文件指针位置写入字符 'B'
。
调用 ftell(fp)
:
获取当前文件指针相对于文件开头的字节偏移,赋值给 sizebite
。
打印当前文件指针偏移量 sizebite
。
int main()
{FILE *fp = fopen("./1.txt","w");if(NULL == fp){printf("fopen errro\n");return -1;}fseek(fp, 11, SEEK_SET);fputc('A', fp);fseek(fp, -3, SEEK_CUR);fputc('B', fp);long sizebite = ftell(fp);printf("%ld\n",sizebite);return 0;
}
4.download
参数检查:要求程序运行时传入两个参数——源文件路径和目标文件路径。
打开文件:以读模式打开源文件 srcfile
。以写模式打开目标文件 destfile
。
获取源文件大小:使用 fseek(srcfile, 0, SEEK_END)
将文件指针定位到末尾。
使用 ftell(srcfile)
获取文件大小(字节数)。
使用 rewind(srcfile)
重置源文件指针到开头。
预分配目标文件空间:使用 fseek(destfile, sizebite - 1, SEEK_SET)
将目标文件指针定位到大小减1的位置。
使用 fputc('\0', destfile)
写入一个空字符,确保文件大小扩展到与源文件相同。
如果写入失败(返回 EOF
),打印“空间不足”错误并退出。
将目标文件指针复位到文件开头,准备写入数据。
循环读取并写入数据:从源文件循环读取最多200字节到缓冲区。
将读取到的数据写入目标文件。直到读取完源文件所有内容。
关闭文件,完成复制。
#include <stddef.h>
#include<stdio.h>int main(int argc, char const *argv[])
{if(argc < 3){printf("Usage: ./a.out <srcfile> <destfile>\n");return -1;}FILE *srcfile = fopen(argv[1],"r");FILE *destfile = fopen(argv[2],"w");if(NULL == srcfile || NULL == destfile){printf("fopen error\n");return -1;}fseek(srcfile, 0, SEEK_END);long sizebite = ftell(srcfile);rewind(srcfile);fseek(destfile, sizebite - 1, SEEK_SET);int ret = fputc('\0', destfile);if(EOF == ret){printf("空间不足\n");fclose(srcfile);fclose(destfile);return -1;}rewind(destfile);char buffer[200] = {0};while(1){size_t counter = fread(buffer, 1, sizeof(buffer), srcfile);if(0 == counter){break;}fwrite(buffer, 1, counter, destfile);}fclose(srcfile);fclose(destfile);return 0;}