C語言—文件操作
1.1 fgetc() + fputc(): 以 字符 形式存取數據定義文件指針
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstdlib> 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 <cstdlib> #include <cstdio> 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 <cstdio> #include <iostream> #include <cstdlib> #include <cstring> 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 <cstdio> #include <iostream> #include <cstdlib> #include <cstring> 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 <cstdio> #include <cstdlib> 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 <iostream> #include <cstdlib> #include <cstdio> 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; }

