C语言—文件操作
1.1 fgetc() + fputc(): 以 字符 形式存取数据定义文件指针
#define _CRT_SECURE_NO_WARNINGS#include#include using namespace std;/*文件结束标志: EOF --- feof()读写文件:fgetc: file get char 以字符形式获取fputc: file put char 以字符形式写到文件*/int main(){ //定义文件指针 FILE *fp; //打开文件 fp = fopen("fopen_01.txt", "w+"); //判断文件打开是否成功 if (!fp) { printf("打开文件失败\n"); exit(0); } //写的方式: 自己移动 fputc('a', fp); fputc('b', fp); fputc('c', fp); //打开文件 fclose(fp); //只读文件 FILE *read = fopen("fopen_01.txt", "r"); if (!read) { printf("打开文件失败\n"); exit(0); } //读文件 //fgetc(): 放回int值, 以字符形式获取 int ch = fgetc(read); while (ch != EOF) { putchar(ch); //打印字符到命令行 ch = fgetc(read); } printf("\n"); fclose(read); return 0;}
2.2 fgets() + fputs(): 以 字符串 形式存取数据
#define _CRT_SECURE_NO_WARNINGS#include#include using namespace std;/*int fputs(char *str, FILE *fp);char* fgets(char *str, int n, FILE *fp);*/int main(){ FILE *fp = fopen("fgets_fputs_02.txt", "w+"); if (!fp) { printf("打开文件失败"); exit(1); } //写的方式: 自己移动 int isok = fputs("Douzi is cute\n I love china!\n who are you?", fp); //返回非负值,表示成功 printf("返回非负值表示成功: %d\n", isok); fclose(fp); FILE *read = fopen("fgets_fputs_02.txt", "r"); if (!read) { printf("打开文件失败\n"); exit(1); } //读文件 char str[50] = ""; //设置读取的长度 while (fgets(str, 50, read)) { puts(str); } //puts(str); fclose(read); return 0;}
2.3 fread() + fwrite(): 以 二进制 形式存取数据
2.3.1 结构体数据
#define _CRT_SECURE_NO_WARNINGS#include#include #include #include using namespace std;/*//以二进制形式存储数据int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)//以什么方式写进去就以什么方式读出 !!int fread(void *buffer,unsigned size, unsigned count, FILE * fp)*/struct student{ char name[20]; int age; double num;}mystudent;int main(){ //写文件 FILE *fp = fopen("fread_fwrite_03.bat", "wb"); if (fp == NULL) { printf("打开失败\n"); exit(1); } while (true) { printf("输入姓名-年龄-成绩:\n"); scanf("%s%d%lf", &mystudent.name, &mystudent.age, &mystudent.num); //参数: 源起始位置, 写多少(字节), 写的次数, 目的地 // &mystudent, sizeof(struct student), 1, fp fwrite(&mystudent, sizeof(struct student), 1, fp); printf("是否继续?(Y/N)"); //清除缓冲区 //否则下面的字符无法输入,因为上面输入按下回车,"回车"会被下面的getchar()吃掉,而无法自己输入 fflush(stdin); int ch = getchar(); if (ch == 'N' || ch == 'n') { break; } } fclose(fp); //读取文件 FILE *read = fopen("fread_fwrite_03.bat", "rb"); if (!read) { printf("文件打开失败\n"); exit(1); } //以二进制形式读取 while (fread(&mystudent, sizeof(struct student), 1, read) > 0) { printf("姓名\t年龄\t成绩:\n"); printf("%s\t%d\t%.2f\n", mystudent.name, mystudent.age, mystudent.num); } fclose(read); return 0;}
2.3.2 结构体数组
#define _CRT_SECURE_NO_WARNINGS#include#include #include #include using namespace std;/*//以二进制形式存储数据int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)//以什么方式写进去就以什么方式读出 !!int fread(void *buffer,unsigned size, unsigned count, FILE * fp): count: 知道有多少数据可以读取*/const int maxn = 1024 + 10;struct student{ char name[20]; int age; double num;}stus[maxn];int main(){ ////写文件 FILE *fp = fopen("fread_fwrite_03.bat", "wb"); if (fp == NULL) { printf("打开失败\n"); exit(1); } int cnt; scanf("%d", &cnt); for (int i = 0; i < cnt; i++) { printf("输入姓名-年龄-成绩:\n"); scanf("%s%d%lf", &stus[i].name, &stus[i].age, &stus[i].num); //清除缓冲区 //否则下面的字符无法输入,因为上面输入按下回车,"回车"会被下面的getchar()吃掉,而无法自己输入 fflush(stdin); } //参数: 源起始位置, 写多少(字节), 写的次数, 目的地 // stus, sizeof(struct student), cnt, fp fwrite(stus, sizeof(struct student), cnt, fp); fclose(fp); //读取文件 FILE *read = fopen("fread_fwrite_03.bat", "rb"); if (!read) { printf("文件打开失败\n"); exit(1); } student read_demo[maxn]; fread(read_demo, sizeof(struct student), cnt, read); for (int i = 0; i < cnt; i++){ printf("姓名\t年龄\t成绩:\n"); printf("%s\t%d\t%.2f\n", read_demo[i].name, read_demo[i].age, read_demo[i].num); } return 0;}
2.4 fprintf() + fscanf():模式化读写文件数据
#define _CRT_SECURE_NO_WARNINGS#include#include using namespace std;/*//printf: 多了指定位置//参数: 指定位置, 与printf一样的格式化【类似%d这样】, 参数列表int fscanf(FILE *fp, char *format, arg_list);int fprintf(FILE *fp, char *format, arg_list); stdin: 标准输入 -- 键盘输入 stdout: 标准输出 -- 屏幕输出 FILE *: 自定义输入输出*/const int maxn = 20;struct Student{ char name[maxn]; int age; double score;} mystu, stu[maxn];int main(){ //写文件 ////标准输入输出 //printf("请输入姓名,年龄,成绩: \n"); //fscanf(stdin, "%s%d%lf", mystu.name, &mystu.age, &mystu.score); //fprintf(stdout, "%s\t%d\t%.1f\n", mystu.name, mystu.age, mystu.score); FILE *fp = fopen("fscanf_fprintf_04.txt", "w+"); if (!fp) { printf("failure!\n"); exit(1); } while (true) { printf("输入姓名-年龄-成绩: \n"); //标准输入,写入文件 fscanf(stdin, "%s%d%lf", mystu.name, &mystu.age, &mystu.score); //写入文件 fprintf(fp, "%s\t%d\t%.2f\n", mystu.name, mystu.age, mystu.score); fflush(stdin); printf("是否继续?(Y/N)"); int ch = getchar(); if (ch == 'N' || ch == 'n') { break; } } fclose(fp); //读文件 FILE *read = fopen("fscanf_fprintf_04.txt", "r+"); if (!read) { printf("failure\n"); exit(1); } while (fscanf(read, "%s%d%lf", mystu.name, &mystu.age, &mystu.score) > 0) { //标准输出 fprintf(stdout, "%s\t%d\t%.2f\n", mystu.name, mystu.age, mystu.score); } fclose(read);}
3.1 文件指针: fseek() + rewind()
-
ftell(fp): 现在所在位置(可用来求数据个数)
#define _CRT_SECURE_NO_WARNINGS#include#include #include using namespace std;/*fseek: fseek(文件类型指针, 位移量, 起始点) 位移量必须是long类型起始点: (宏)SEEK_SET 文件首 0;SEEK_CUR 文件当前位置 1;SEEK_END 文件尾部 2;以二进制形式存储数据int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)//以什么方式写进去就以什么方式读出 !!int fread(void *buffer,unsigned size, unsigned count, FILE * fp)*/struct Student{ char name[20]; int age; double num;}stus[20];int main(){ //以二进制形式写文件 FILE *fp = fopen("fseek_rewind_06.txt", "wb+"); if (!fp) { printf("failure!\n"); exit(1); } int N; cin >> N; for (int i = 0; i < N; i++) { printf("输入姓名-年龄-分数:\n"); scanf("%s%d%lf", stus[i].name, &stus[i].age, &stus[i].num); fflush(stdin); } //写入文件 //存N个数据 fwrite(stus, sizeof(struct Student), N, fp); //fseek(文件类型指针, 位移量, 起始点) 位移量必须是long类型 //SEEK_SET 文件首 0; //注意点: 移动多个位置, long L :表示 //正负: 往后- 往前+ fseek(fp, 0, SEEK_SET); //移动到第二个数据位置 Student tmp; fseek(fp, 1L * sizeof(struct Student), SEEK_SET); fread(&tmp, sizeof(struct Student), 1, fp); printf("第二个数据: \n"); printf("%s\t%d\t%.2f\n", tmp.name, tmp.age, tmp.num); //移动到最后一个位置(之后无元素) fseek(fp, 0, SEEK_END); long size = ftell(fp); //ftell:现在所在位置(表达这个文件的大小) int number = size / sizeof(Student); printf("有几个数据%d: \n", number); //移动到最后一个元素之前位置 位移量必须是long类型,需要类型转换 fseek(fp, -1L * (long)sizeof(struct Student), SEEK_END); fread(&tmp, sizeof(struct Student), 1, fp); printf("最后一个元素: \n"); printf("%s\t%d\t%.2f\n", tmp.name, tmp.age, tmp.num); //直接移动到文件开始位置 Student stu[20]; rewind(fp); printf("全部数据: \n"); int len = fread(stu, sizeof(struct Student), N, fp); for (int i = 0; i < len; i++){ printf("%s\t%d\t%.2f\n", stu[i].name, stu[i].age, stu[i].num); } fclose(fp); return 0;}