实验7
一.实验任务1
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 // 文件读写操作:格式化读、写文本文件 3 #include <stdio.h> 4 5 #define N 80 6 #define M 100 7 8 typedef struct { 9 char name[N]; // 书名 10 char author[N]; // 作者 11 } Book; 12 13 void write(); 14 void read(); 15 16 int main() { 17 printf("测试1: 把图书信息写入文本文件\n"); 18 write(); 19 20 printf("\n测试2: 从文本文件读取图书信息, 打印输出到屏幕\n"); 21 read(); 22 23 return 0; 24 } 25 26 void write() { 27 Book x[] = { {"《雕塑家》", "斯科特.麦克劳德"}, 28 {"《灯塔》", "克里斯多夫.夏布特"}, 29 {"《人的局限性》", "塞缪尔.约翰生"}, 30 {"《永不停步:玛格丽特.阿特伍德传》", "罗斯玛丽.沙利文"}, 31 {"《大地之上》", "罗欣顿·米斯特里"}, 32 {"《上学记》", "何兆武"}, 33 {"《命运》", "蔡崇达"} }; 34 int n, i; 35 FILE *fp; 36 37 // 计算数组x中元素个数 38 n = sizeof(x) / sizeof(x[0]); 39 40 // 以写的方式打开文本文件data1.txt 41 fp = fopen("data1.txt", "w"); 42 43 // 如果打开文件失败,输出提示信息并返回 44 if(fp == NULL) { 45 printf("fail to open file to write\n"); 46 return; 47 } 48 49 // 将结构体数组x中的图书信息格式化写到fp指向的文件data1.txt 50 for(i = 0; i < n; ++i) 51 fprintf(fp, "%-40s %-20s\n", x[i].name, x[i].author); 52 53 fclose(fp); 54 } 55 56 void read() { 57 Book x[M]; 58 int i, n; 59 int number; 60 61 FILE *fp; 62 63 // 以读的方式打开文本文件data1.txt 64 fp = fopen("data1.txt", "r"); 65 66 // 如果打开文件失败,输出提示信息并返回 67 if(fp == NULL) { 68 printf("fail to open file to read\n"); 69 return; 70 } 71 72 // 从文件中读取图书信息,保存到结构体数组x中 73 i = 0; 74 while(!feof(fp)) { 75 number = fscanf(fp, "%s%s", x[i].name, x[i].author); 76 if(number != 2) 77 break; 78 i++; 79 } 80 n = i; 81 82 // 将图书信息打印输出到屏幕上 83 for(i = 0; i < n; ++i) 84 printf("%d. %-40s%-20s\n", i+1, x[i].name, x[i].author); 85 86 fclose(fp); 87 }
程序运行结果截图:

回答:当去掉line75.76后,会出现乱码。这行代码的作用是跳出循环,避免不合理的数据被处理。
二.实验任务2
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 // 文件读写操作:以数据块方式读、写二进制文件 3 4 #include <stdio.h> 5 6 #define N 80 7 #define M 100 8 9 typedef struct { 10 char name[N]; // 书名 11 char author[N]; // 作者 12 } Book; 13 14 void write(); 15 void read(); 16 17 int main() { 18 printf("测试1: 把图书信息以数据块方式写入二进制文件\n"); 19 write(); 20 21 printf("\n测试2: 从二进制文件读取图书信息, 打印输出到屏幕\n"); 22 read(); 23 24 return 0; 25 } 26 27 void write() { 28 Book x[] = { {"《雕塑家》", "斯科特.麦克劳德"}, 29 {"《灯塔》", "克里斯多夫.夏布特"}, 30 {"《人的局限性》", "塞缪尔.约翰生"}, 31 {"《永不停步:玛格丽特.阿特伍德传》", "罗斯玛丽.沙利文"}, 32 {"《大地之上》", "罗欣顿·米斯特里"}, 33 {"《上学记》", "何兆武"}, 34 {"《命运》", "蔡崇达"} }; 35 int n; 36 FILE *fp; 37 38 // 计算数组x中元素个数 39 n = sizeof(x) / sizeof(x[0]); 40 41 // 以写的方式打开二进制文件data2.dat 42 fp = fopen("data2.dat", "wb"); 43 44 // 如果打开文件失败,输出提示信息并返回 45 if(fp == NULL) { 46 printf("fail to open file to write\n"); 47 return; 48 } 49 50 // 将结构体数组x中的图书信息以数据块方式写入二进制文件data2.dat 51 fwrite(x, sizeof(Book), n, fp); 52 53 fclose(fp); 54 } 55 56 void read() { 57 Book x[M]; 58 int i, n; 59 int number; 60 61 FILE *fp; 62 63 // 以读的方式打开二进制文件data2.dat 64 fp = fopen("data2.dat", "rb"); 65 66 // 如果打开文件失败,输出提示信息并返回 67 if(fp == NULL) { 68 printf("fail to open file to read\n"); 69 return; 70 } 71 72 // 从二进制文件data2.dat以数据块方式读取图书信息存储到结构体数组x 73 i = 0; 74 while(!feof(fp)) { 75 number = fread(&x[i], sizeof(Book), 1, fp); 76 if(number != 1) 77 break; 78 i++; 79 } 80 81 // 在屏幕上打印输出 82 n = i; 83 for(i = 0; i < n; ++i) 84 printf("%d. %-40s%-20s\n", i+1, x[i].name, x[i].author); 85 86 fclose(fp); 87 }
程序运行结果截图:

回答:line75.76两行代码和上一个实验任务的作用相似,就是确保程序能安全的读取有效数据
三.实验任务3
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 // 文件读写操作:以字符、字符串形式读、写 3 4 #include <stdio.h> 5 #define N 5 6 #define M 80 7 8 void write(); 9 void read_str(); 10 void read_char(); 11 12 int main() { 13 printf("测试1: 把一组字符信息以字符串方式写入文本文件\n"); 14 write(); 15 16 printf("\n测试2: 从文件以字符串方式读取, 输出到屏幕\n"); 17 read_str(); 18 19 printf("\n测试3: 从文件以单个字符方式读取, 输出到屏幕\n"); 20 read_char(); 21 22 return 0; 23 } 24 25 void write() { 26 char *ptr[N] = { "Working\'s Blues", 27 "Everything Will Flow", 28 "Streets of London", 29 "Perfect Day", 30 "Philadelphia"}; 31 int i; 32 FILE *fp; 33 34 fp = fopen("data3.txt", "w"); 35 if(!fp) { 36 printf("fail to open file to write\n"); 37 return; 38 } 39 40 for(i = 0; i < N; ++i) { 41 fputs(ptr[i], fp); 42 fputs("\n", fp); 43 } 44 45 fclose(fp); 46 } 47 48 void read_str() { 49 char songs[N][M]; 50 int i; 51 FILE *fp; 52 53 fp = fopen("data3.txt", "r"); 54 if(!fp) { 55 printf("fail to open file to read\n"); 56 return; 57 } 58 59 for(i = 0; i < N; ++i) 60 fgets(songs[i], 80, fp); 61 62 for(i = 0; i < N; ++i) 63 printf("%d. %s", i+1, songs[i]); 64 65 fclose(fp); 66 } 67 68 void read_char() { 69 char ch; 70 FILE *fp; 71 72 fp = fopen("data3.txt", "r"); 73 if(!fp) { 74 printf("fail to open file to read\n"); 75 return; 76 } 77 78 while(!feof(fp)) { 79 ch = fgetc(fp); 80 if(ch == EOF) 81 break; 82 83 putchar(ch); 84 } 85 86 fclose(fp); 87 }
程序运行结果截图:

回答:因为在这个代码中,反斜杠'\'是转义字符,他后面跟了',意思是告诉编译器这里的'是一个字符,而不是字符串结束标志。因此不会生产反斜杠。
四.实验任务4
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 4 #define N 3 5 6 void write(); 7 void count(); 8 9 int main() { 10 printf("测试1: 把数据写入文本文件\n"); 11 write(); 12 13 printf("\n测试2: 统计文件的行数和非空白字符数\n"); 14 count(); 15 16 return 0; 17 } 18 19 void write() { 20 const char* lines[N] = { 21 "0123456789-0123456789", 22 "nuist2025", 23 "cosmos galaxy" 24 }; 25 FILE* fp = fopen("data4.txt", "w"); 26 if (!fp) { 27 printf("fail to open file to write\n"); 28 return; 29 } 30 for (int i = 0; i < N; ++i) { 31 fputs(lines[i], fp); 32 fputs("\n", fp); 33 } 34 fclose(fp); 35 } 36 37 int is_whitespace(int ch) { 38 return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; 39 } 40 41 void count() { 42 FILE* fp = fopen("data4.txt", "r"); 43 if (!fp) { 44 printf("fail to open file to read\n"); 45 return; 46 } 47 int ch, lines = 0, chars = 0; 48 while ((ch = fgetc(fp)) != EOF) { 49 if (ch == '\n') 50 lines++; 51 if (!is_whitespace(ch)) 52 chars++; 53 } 54 fseek(fp, -1, SEEK_END); 55 if (ftell(fp) >= 0) { 56 ch = fgetc(fp); 57 if (ch != '\n') 58 lines++; 59 } 60 fclose(fp); 61 printf("行数: %d\n", lines); 62 printf("非空白字符数: %d\n", chars); 63 }
程序运行结果截图:

五.实验任务5
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include <stdio.h> 3 #include <string.h> 4 5 #define N 10 6 7 typedef struct { 8 long id; // 准考证号 9 char name[20]; // 姓名 10 float objective; // 客观题得分 11 float subjective; // 操作题得分 12 float sum; // 总分 13 char result[10]; // 考试结果 14 } STU; 15 16 // 函数声明 17 void read(STU st[], int n); 18 void write(STU st[], int n); 19 void output(STU st[], int n); 20 int process(STU st[], int n, STU st_pass[]); 21 22 int main() { 23 FILE* fp = fopen("examinee.txt", "w"); 24 if (!fp) { 25 printf("fail to open file\n"); 26 return 1; 27 } 28 fprintf(fp, "1001\t桃乐丝\t36\t55\n"); 29 fprintf(fp, "1002\t稻草人\t28\t40\n"); 30 fprintf(fp, "1003\t千寻\t39\t55\n"); 31 fprintf(fp, "1004\t白龙\t35\t60\n"); 32 fprintf(fp, "1005\t汤婆婆\t20\t35\n"); 33 fprintf(fp, "1006\t无脸男\t33\t50\n"); 34 fprintf(fp, "1007\t希达\t40\t32\n"); 35 fprintf(fp, "1008\t巴鲁\t28\t30\n"); 36 fprintf(fp, "1009\t苏菲\t37\t60\n"); 37 fprintf(fp, "1010\t哈尔\t35\t57\n"); 38 fclose(fp); 39 printf("examinee.txt 文件已生成!\n"); 40 41 STU stu[N], stu_pass[N]; 42 int cnt; 43 double pass_rate; 44 45 printf("从文件读入%d个考生信息...\n", N); 46 read(stu, N); 47 48 printf("\n对考生成绩进行统计...\n"); 49 cnt = process(stu, N, stu_pass); 50 51 printf("\n通过考试的名单:\n"); 52 output(stu, N); // 输出所有考生完整信息到屏幕 53 write(stu, N); // 输出考试通过的考生信息到文件 54 55 pass_rate = 1.0 * cnt / N; 56 printf("\n本次等级考试通过率: %.2f%%\n", pass_rate * 100); 57 58 return 0; 59 } 60 61 // 把所有考生完整信息输出到屏幕上 62 // 准考证号,姓名,客观题得分,操作题得分,总分,结果 63 void output(STU st[], int n) { 64 int i; 65 66 printf("准考证号\t姓名\t客观题得分\t操作题得分\t总分\t\t结果\n"); 67 for (i = 0; i < n; i++) 68 printf("%ld\t\t%s\t%.2f\t\t%.2f\t\t%.2f\t\t%s\n", st[i].id, st[i].name, st[i].objective, st[i].subjective, st[i].sum, st[i].result); 69 } 70 71 // 从文本文件examinee.txt读入考生信息:准考证号,姓名,客观题得分,操作题得分 72 void read(STU st[], int n) { 73 int i; 74 FILE* fin; 75 76 fin = fopen("examinee.txt", "r"); 77 if (!fin) { 78 printf("fail to open file\n"); 79 return; 80 } 81 82 while (!feof(fin)) { 83 for (i = 0; i < n; i++) 84 fscanf(fin, "%ld %s %f %f", &st[i].id, st[i].name, &st[i].objective, &st[i].subjective); 85 } 86 87 fclose(fin); 88 } 89 90 // 把通过考试的考生完整信息写入文件list_pass.txt 91 // 准考证号,姓名,客观题得分,操作题得分,总分,结果 92 void write(STU s[], int n) { 93 int i; 94 FILE* fp; 95 fp = fopen("list_pass.txt", "w"); 96 fprintf(fp, "%-10s %-8s %-10s %-10s %-10s %-8s\n", "准考证号", "姓名", "客观题得分", "操作题得分", "总分", "结果"); 97 for (i = 0; i < n; i++) { 98 if (s[i].sum >= 60) 99 fprintf(fp, "%-10ld %-8s %-10.2f %-10.2f %-10.2f %-8s\n", s[i].id, s[i].name, s[i].objective, s[i].subjective, s[i].sum, s[i].result); 100 } 101 fclose(fp); 102 } 103 104 // 对考生信息进行处理:计算每位考生考试总分、结果;统计考试通过的人数 105 int process(STU st[], int n, STU st_pass[]) { 106 int i, j; 107 for (i = 0; i < n; ++i) { 108 st[i].sum = st[i].objective + st[i].subjective; 109 } 110 for (i = 0, j = 0; i < n; ++i) { 111 if (st[i].sum >= 60) { 112 strcpy(st[i].result, "通过"); 113 st_pass[j] = st[i]; 114 j++; 115 } 116 else { 117 strcpy(st[i].result, "不通过"); 118 } 119 } 120 return j; 121 }
程序运行结果截图:

六.实验任务6
实验代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <time.h> 5 6 #define MAX 100 7 #define WIN_NUM 5 8 9 void read_list(const char* filepath, char arr[][100], int* n); 10 void draw(int n, int result[]); 11 void print_winner(char arr[][100], int result[]); 12 13 int main() { 14 printf("测试1: 从文件读取名单\n"); 15 char data[MAX][100]; 16 int n = 0; 17 const char* filepath = "D:\\Data\\list.txt"; 18 read_list(filepath, data, &n); 19 20 printf("\n测试2: 随机抽取%d个中奖名单\n", WIN_NUM); 21 int result[WIN_NUM]; 22 draw(n, result); 23 24 printf("\n测试3: 在终端打印中奖名单\n"); 25 print_winner(data, result); 26 27 printf("\n抽奖完成!\n"); 28 return 0; 29 } 30 31 void read_list(const char* filepath, char arr[][100], int* n) { 32 FILE* fp = fopen(filepath, "r"); 33 if (!fp) { 34 printf("fail to open file to read: %s\n", filepath); 35 return; 36 } 37 while (fgets(arr[*n], 100, fp)) { 38 char* p = arr[*n]; 39 while (*p && *p != '\n' && *p != '\r') p++; 40 *p = '\0'; 41 (*n)++; 42 } 43 fclose(fp); 44 printf("共读取到%d条数据\n", *n); 45 } 46 47 void draw(int n, int result[]) { 48 int used[MAX] = { 0 }; 49 int count = 0; 50 srand((unsigned int)time(NULL)); 51 while (count < WIN_NUM) { 52 int idx = rand() % n; 53 if (!used[idx]) { 54 result[count++] = idx; 55 used[idx] = 1; 56 } 57 } 58 printf("抽取的中奖序号为:"); 59 for (int i = 0; i < WIN_NUM; ++i) 60 printf("%d ", result[i] + 1); 61 printf("\n"); 62 } 63 64 void print_winner(char arr[][100], int result[]) { 65 printf("中奖名单如下:\n"); 66 for (int i = 0; i < WIN_NUM; ++i) { 67 printf("%d. %s\n", i + 1, arr[result[i]]); 68 } 69 }
程序运行结果截图:

浙公网安备 33010602011771号