一、C语言进阶:文件操作

编程入门 行业动态 更新时间:2024-10-09 18:22:27

一、C语言<a href=https://www.elefans.com/category/jswz/34/1769503.html style=进阶:文件操作"/>

一、C语言进阶:文件操作

1 文件操作

1.1 文件的输入输出

输出:使用printf()和命令行重定向>实现文件输出;
输入:使用scanf()和命令行重定向<实现文件输入。

#include <stdio.h>
//printf() 写入文件 ./a.out > hello.txt
//scanf() 从文件读 ./a.out < hello.txt
int main(){char name[20];scanf("%s",name);printf("Hello %s!\n",name);
}

1.2 文件打开fopen()和关闭fclose()

fopen()函数原型:

FILE *fopen(char restrict *filename, char restrict *mode);

restrict C99标准才引进的,属于类型修饰符,表示修饰的这块内存空间只能被这个指针引用和修改,除此之外别无他法。

如果文件顺利打开,则返回值是指向这个文件流的文件指针,如果文件打开失败,返回NULL。

  • filename:需要打开的文件
  • mode:打开方式
    mode的几种类型
    1、r: 读
    2、w: 写
    3、a: 追加
    4、+: 读或写,配合r、w、a使用
    5、t: 文本文件
    6、b: 二进制文件
    注:a只能追加不能修改,w会把文件清空,r+读写方式可以修改文件原有内容。

fclose()函数原型:

int flcose(FILE* stream);

stream: 函数指针
返回值:成功返回0,否则返回-1

1.3 文本读写fprintf()fscanf()

  • 函数原型
int fprintf(FILE *stream, char *format, argument...);
int fscanf(FILE *stream, char *format, argument... );

fprintf()/fscanf()printf()/scanf()使用非常相似,区别在于fprintf()/fscanf()第一个参数stream是文件描述符。

  • 实例:
#include <stdio.h>
int main(){char name[20];fscanf(stdin,"%s",name); //stdin标准读,从终端读fprintf(stdout,"Hello %s!\n",name); //stdout标准写,向终端写
}
  • 实例:学生信息的读入读出
#include <stdio.h>
typedef struct{char name[20];int age;float score;
} Stu;
int main(){FILE* pfile = fopen("./student","r");if(NULL == pfile){printf("file is not exited!\n");return 1;}int n;fscanf(pfile,"%d",&n);Stu s[n];for(int i = 0;i < n;++i){fscanf(pfile,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);}fclose(pfile);pfile = NULL;FILE* pfile2 = fopen("./student2","w");if(NULL == pfile2){printf("file ./student2 is not exited!\n");return 1;}for(int i = 0;i < n;++i){fprintf(pfile2,"%s %d %.2f\n",s[i].name,s[i].age,s[i].score);}fclose(pfile2);pfile2 = NULL;
}
  • 学生信息管理: 采用fprintf()fscanf() 实现增删查改
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct{char name[20];int age;float score;
} Stu;
bool Load(const char* path,Stu* s,int* n){FILE* file = fopen(path,"r");if(NULL == file){printf("file is not exited!\n");return false;}int m;fscanf(file,"%d",&m);*n = m;for(int i = 0;i < m;++i){fscanf(file,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);}fclose(file);file = NULL;return true;
}
void ShowStudents(Stu* s,int n){for(int i = 0;i < n;++i){printf("%s %d %f\n",s[i].name,s[i].age,s[i].score);}
}
void SaveStudents(const char* path,Stu* s,int* n){FILE* file = fopen(path,"w");if(NULL == file){printf("file is not exited!\n");return;}fprintf(file,"%d\n",*n);for(int i = 0;i < *n;++i){fprintf(file,"%s %d %f\n",s[i].name,s[i].age,s[i].score);}fclose(file);file = NULL;
}
void Register(const char* path,Stu* s,int* n){int before = *n;printf("请输入录入学生个数:");int append_num;scanf("%d",&append_num);*n += append_num;printf("请依次输入学生姓名,年龄和成绩:\n");for(int i = before;i < *n;++i){scanf("%s%d%f",&s[i].name,&s[i].age,&s[i].score);}SaveStudents(path,s,n);
}
int cmp(const void* a,const void* b){return ((Stu*)(a))->score < ((Stu*)(b))->score?1:-1;
}
void SortStudents(Stu* s,int n){qsort(s,n,sizeof(Stu),cmp);ShowStudents(s,n);
}
void SearchStudents(Stu* s,int n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < n;++i){if(strcmp(name,s[i].name) == 0){found = true;printf("查询结果:%s %d %f\n",s[i].name,s[i].age,s[i].score);}}if(!found){printf("查无此人!\n");}
}
void DeleteStudents(const char* path,Stu* s,int* n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < *n;++i){if(strcmp(name,s[i].name) == 0){found = true;for(int j = i+1;j < *n;++j){s[i++] = s[j];}*n -= 1;printf("删除成功!\n");break;}}if(!found){printf("查无此人!\n");return;}SaveStudents(path,s,n);
}void ModifyStudents(const void* path,Stu* s,int n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < n;++i){if(strcmp(name,s[i].name) == 0){found = true;printf("请依次输入修改后的信息:姓名 年龄 成绩\n");scanf("%s%d%f",&s[i].name,&s[i].age,&s[i].score);break;}}if(!found){printf("查无此人!\n");return;}SaveStudents(path,s,&n);
}
int main(){const char* data = "./student.txt";Stu s[10];int n;if(Load(data,s,&n)){printf("已经加载%d名学生信息\n",n);  }while(true){printf("功能列表:\n");printf("1.查看所有学生信息\n");printf("2.录入学生信息\n");printf("3.按成绩排序\n");printf("4.查询学生信息\n");printf("5.删除学生信息\n");printf("6.修改学生信息 \n");printf("0.退出\n");int num;scanf("%d",&num);switch(num){case 1: ShowStudents(s,n);break;case 2:Register(data,s,&n);break;case 3:SortStudents(s,n);break;case 4:SearchStudents(s,n);break;case 5:DeleteStudents(data,s,&n);break;case 6:ModifyStudents(data,s,n);break;case 0:return 0;}}
}

1.4 二进制读和写:fread()和fwrite()

  • 函数原型
size_t fread(void *ptr, size_t size, size_t count, FILE* stream);
size_t fwrite(void *ptr, size_t size, size_t count, FILE* stream);

ptr: 一个指针,在fread()中是从文件里读入的数据存放的地址;在fwrite()中是写入到文件里的数据存放的地址。

ptr指针,在fread()中是从文件里读入的数据存放的地址;在fwrite()中是写入到文件里的数据存放的地址
size每次要读写的字节数
count读写的次数
stream文件指针
  • 返回值:成功读取/写入的字节数
  • 实例:fread()和fwrite()实现文件读和写
#include <stdio.h>
#include <string.h>
int main(){FILE* fp= fopen("./hello.txt","rw");char str[] = "Hello World";fwrite(str,sizeof(str),1,fp);char str1[20];fread(str1,sizeof(str1),1,fp);printf("%s\n",str1);
}
  • 学生信息管理: 采用fread()和fwrite() 实现增删查改
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct{char name[20];int age;float score;
} Stu;
bool Load(const char* path,Stu* s,int* n){FILE* file = fopen(path,"rb");if(NULL == file){printf("file is not exited!\n");return false;}int m;fread(&m,sizeof(m),1,file);//fscanf(file,"%d",&m);*n = m;fread(s,sizeof(Stu),m,file);/*for(int i = 0;i < m;++i){fscanf(file,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);}*/fclose(file);file = NULL;return true;
}
void ShowStudents(Stu* s,int n){for(int i = 0;i < n;++i){printf("%s %d %f\n",s[i].name,s[i].age,s[i].score);}
}
void SaveStudents(const char* path,Stu* s,int n){FILE* file = fopen(path,"wb");if(NULL == file){printf("file is not exited!\n");return;}fwrite(&n,sizeof(n),1,file);//fprintf(file,"%d\n",*n);fwrite(s,sizeof(Stu),n,file);/*for(int i = 0;i < *n;++i){fprintf(file,"%s %d %f\n",s[i].name,s[i].age,s[i].score);}*/fclose(file);file = NULL;
}
void Register(const char* path,Stu* s,int* n){int before = *n;printf("请输入录入学生个数:");int append_num;scanf("%d",&append_num);*n += append_num;printf("请依次输入学生姓名,年龄和成绩:\n");for(int i = before;i < *n;++i){scanf("%s%d%f",&s[i].name,&s[i].age,&s[i].score);}SaveStudents(path,s,*n);
}
int cmp(const void* a,const void* b){return ((Stu*)(a))->score < ((Stu*)(b))->score?1:-1;
}
void SortStudents(Stu* s,int n){qsort(s,n,sizeof(Stu),cmp);ShowStudents(s,n);
}
void SearchStudents(Stu* s,int n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < n;++i){if(strcmp(name,s[i].name) == 0){found = true;printf("查询结果:%s %d %f\n",s[i].name,s[i].age,s[i].score);}}if(!found){printf("查无此人!\n");}
}
void DeleteStudents(const char* path,Stu* s,int* n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < *n;++i){if(strcmp(name,s[i].name) == 0){found = true;for(int j = i+1;j < *n;++j){s[i++] = s[j];}*n -= 1;printf("删除成功!\n");break;}}if(!found){printf("查无此人!\n");return;}SaveStudents(path,s,*n);
}void ModifyStudents(const void* path,Stu* s,int n){printf("请输入学生姓名:");char name[20];scanf("%s",name);bool found = false;for(int i = 0;i < n;++i){if(strcmp(name,s[i].name) == 0){found = true;printf("请依次输入修改后的信息:姓名 年龄 成绩\n");scanf("%s%d%f",&s[i].name,&s[i].age,&s[i].score);break;}}if(!found){printf("查无此人!\n");return;}SaveStudents(path,s,n);
}
int main(){const char* data = "./student2.dat";Stu s[10];int n;if(Load(data,s,&n)){printf("已经加载%d名学生信息\n",n);  }while(true){printf("功能列表:\n");printf("1.查看所有学生信息\n");printf("2.录入学生信息\n");printf("3.按成绩排序\n");printf("4.查询学生信息\n");printf("5.删除学生信息\n");printf("6.修改学生信息 \n");printf("0.退出\n");int num;scanf("%d",&num);switch(num){case 1: ShowStudents(s,n);break;case 2:Register(data,s,&n);break;case 3:SortStudents(s,n);break;case 4:SearchStudents(s,n);break;case 5:DeleteStudents(data,s,&n);break;case 6:ModifyStudents(data,s,n);break;case 0:return 0;}}
}

注:读取文件须为二进制文件.dat

1.5 文件定位:ftell()fseek()

  • 函数原型
// 获取位置
long ftell(FILE* stream);
// 设置位置
int fseek(FILE* stream,long offset,int whence);
  • 参数
stream文件指针
offset基于起始点的偏移量
whence起始点

whence的集中状态及含义:

whence数值含义
SEEK_SET0从头开始
SEEK_CUR1从当前开始
SEEK_END2从结束开始
  • 返回值
    ftell()返回基于文件开头的偏移字节数。
  • 实例:计算文件大小
#include <stdio.h>
int main() {FILE* fp = fopen("hello.txt","r");if(fp) {fseek(fp,0,SEEK_END);//设置指针为最后位置,便宜0字节long size = ftell(fp); //ftell()返回基于文件开头的偏移字节数。printf("大小为%ldB\n",size);}
}

1.6 文件结尾判断feof()

  • 函数原型
int feof(FILE* stream);
  • 参数
    stream 文件指针
  • 返回值
    若指针指向文件结尾,返回一个真值,否则返回非真值。

1.7 返回开头rewind()

  • 函数原型
void rewind(FILE* stream);
  • 参数
    stream 文件指针
  • 实例
#include <stdio.h>
int main() {FILE* fp = fopen("hello.txt","r");fseek(fp,0,SEEK_END);long len = ftell(fp);printf("%d\n",len);rewind(fp);len = ftell(fp);printf("%d\n",len);
}
13
0

1.8 清空数据流

  • 函数原型
void fflush(FILE* stream);
  • 参数
    stream 文件指针
  • 举例
fflush(fp);        // 清空文件流

更多推荐

一、C语言进阶:文件操作

本文发布于:2024-02-13 17:35:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760084.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:进阶   语言   操作   文件

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!