实验7 文件应用编程

一、实验目的

 知道C语言中文件处理方式,能区分文本文件和二进制文件

会打开/关闭文件,能够对文件进行读/写操作

能综合应用结构体,数组,函数,文件进行应用编程

二、实验准备

 第9章:文件的基础知识,文本文件和二进制文件,路径表示

文件打开/关闭,常用的读写函数的用法

 

三、实验内容

 

1. 实验任务1

问题回答:

去掉if(number!=2)break;之后,程序运行打印输出在屏幕上的多了一个8. 这两行是为了确保判断在当前循环中是否成功读取了两个字符串,如果没有成功读取就结果程序。避免将未完全读取的数据添加到数组当中打印输出。

 

 

 

2. 实验任务2

 

 

问题回答:

 内容不可以直观可见,是一堆韩语和不认识的一些符号。

if(number!=1)break;去年之后,打印输出在屏幕上的内容多了一行是8.

这两行的作用是:检查从二进制文件中读取数据是否成功

 

 

3. 实验任务3

 

 问题回答:

 这是因为这里的反斜杠是一个转义字符,用来转义单引号('),使其不会被解释为字符串的结束。

 

 

4. 实验任务4

代码:

 

 1 // 文件读写操作:以数据块方式读、写二进制文件
 2 
 3 #include <stdio.h>
 4 
 5 
 6 
 7 
 8 
 9 void read();
10 
11 int main() {
12    
13    
14         
15     printf("data.txt统计结果:\n");
16     read();
17     return 0;
18 }
19 
20 
21 
22 void read() {
23     int count_lines=0;//文件当中的的文件行数
24     int count_chars=0;//文件当中的字符数 
25        char ch;
26     FILE *fp;
27     
28     // 以读的方式打开文本文件data4.txt
29     fp = fopen("data4.txt", "r");
30     
31     // 如果打开文件失败,输出提示信息并返回 
32     if(fp == NULL) {
33         printf("fail to open file to read\n");
34         return;
35     }
36     
37     
38  
39   
40     while ((ch = fgetc(fp)) != EOF) {
41         if (ch != ' ' && ch != '\n' && ch != '\t') {
42             count_chars++; // 统计非空白字符
43         }
44         if (ch == '\n') {
45             count_lines++; // 统计行数
46         }
47     }
48    
49 
50     fclose(fp);
51     printf("%-20s: %d\n", "文件行数", count_lines);
52     printf("%-20s: %d\n", "文件字符数(不包括空白符)", count_chars);
53 }

 

 

运行截图:

 

 

 

 

 

 

 

5. 实验任务5

代码:

 

  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 #define N 10
  5 
  6 typedef struct {
  7     long id;            // 准考证号
  8     char name[20];      // 姓名
  9     float objective;    // 客观题得分
 10     float subjective;   // 操作题得分
 11     float sum;          // 总分
 12     char result[10];    // 考试结果
 13 } STU;
 14 
 15 // 函数声明
 16 void read(STU st[], int n);
 17 void write(STU st[], int n);
 18 void output(STU st[], int n);
 19 int process(STU st[], int n, STU st_pass[]);
 20 
 21 int main() {
 22     STU stu[N], stu_pass[N];
 23     int cnt;
 24     double pass_rate;
 25 
 26     printf("从文件读入%d个考生信息...\n", N);
 27     read(stu, N);
 28 
 29     printf("\n对考生成绩进行统计...\n");
 30     cnt = process(stu, N, stu_pass);
 31 
 32     printf("\n通过考试的名单:\n");
 33     output(stu, N);   // 输出所有考生完整信息到屏幕
 34     write(stu, N);    // 输出考试通过的考生信息到文件
 35 
 36     pass_rate = 1.0 * cnt / N;
 37     printf("\n本次等级考试通过率: %.2f%%\n", pass_rate*100);
 38 
 39     return 0;
 40 }
 41 
 42 // 把所有考生完整信息输出到屏幕上
 43 // 准考证号,姓名,客观题得分,操作题得分,总分,结果
 44 void output(STU st[], int n) {
 45     int i;
 46     
 47     printf("准考证号\t姓名\t客观题得分\t操作题得分\t总分\t\t结果\n");
 48     for (i = 0; i < n; i++)
 49         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);
 50 }
 51 
 52 // 从文本文件examinee.txt读入考生信息:准考证号,姓名,客观题得分,操作题得分
 53 void read(STU st[], int n) {
 54     int i;
 55     FILE *fin;
 56 
 57     fin = fopen("examinee.txt", "r");
 58     if (!fin) {
 59         printf("fail to open file\n");
 60         return;
 61     }
 62 
 63     while (!feof(fin)) {
 64         for (i = 0; i < n; i++)
 65             fscanf(fin, "%ld %s %f %f", &st[i].id, st[i].name, &st[i].objective, &st[i].subjective);
 66     }
 67 
 68     fclose(fin);
 69 }
 70 
 71 // 把通过考试的考生完整信息写入文件list_pass.txt
 72 // 准考证号,姓名,客观题得分,操作题得分,总分,结果
 73 void write(STU st[], int n) {
 74     
 75              int i;
 76             FILE *fin;    
 77             //以写的方式打开文件 list_pass.txt
 78                 fin = fopen("list_pass.txt", "w");
 79             if (!fin) 
 80             {
 81             printf("fail to open file\n");
 82             return;
 83             }
 84 
 85     fprintf(fin, "%-15s %-20s %-15s %-15s %-10s %-10s\n", "准考证号", "姓名", "客观题得分", "操作题得分", "总分", "结果");
 86                for (i = 0; i < n; i++)
 87                {
 88                 st[i].sum=st[i].objective+st[i].subjective;
 89                 
 90                 if(    st[i].sum>=60)
 91                 {
 92                     strcpy(st[i].result,"通过"); 
 93                     fprintf(fin, "%-15ld %-20s %-15.2f %-15.2f %-10.2f %-10s\n", st[i].id, st[i].name, st[i].objective, st[i].subjective,st[i].sum,st[i].result);
 94                 }
 95             }    
 96     }
 97 
 98           
 99         
100 
101 
102 
103 // 对考生信息进行处理:计算每位考生考试总分、结果;统计考试通过的人数
104 int process(STU st[], int n, STU st_pass[]) {
105         int j=0;
106         int pass_num=0;    
107         for(int i=0;i<n;i++)
108         {
109             st[i].sum=st[i].objective+st[i].subjective;
110                 
111             if(    st[i].sum>=60)
112                 {
113                     strcpy(st[i].result,"通过");     
114                 }
115                 else
116                 strcpy(st[i].result,"不通过"); 
117         }
118         for(int i=0;i<n;i++)
119         {
120             if(    st[i].sum>=60)
121             {
122                 strcpy(st_pass[j].name,st[i].name);
123                 st_pass[j].objective=st[i].objective;
124                 st_pass[j].subjective=st[i].subjective;
125                 st_pass[j].sum=st[i].sum;
126                 strcpy(st_pass[j].result,st[i].result);
127                 j++;
128                 pass_num++;
129             }
130         }
131        return pass_num;          
132     }

 

 

运行截图:

 

 

 

 

 

6. 实验任务6

必做代码:

 

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<time.h>
  5 
  6 #define MAX_NUM 80    // 生成随机数的范围 0-79
  7 #define SELECTION_COUNT 5  // 选择的随机数个数
  8 #define N 20
  9 #define M 40
 10 
 11 typedef struct {
 12     long id;    // 学号 
 13     char name[N];     // 姓名 
 14     char class[M];  //班级 
 15 } STU;
 16 
 17 // 生成随机不重复的索引数组
 18 void generateRandomIndices(int selected[]);
 19 // 从文件读取学生信息到数组
 20 void read(STU stu[]);
 21 // 根据索引数组将选中的学生信息提取出来
 22 void extractSelectedStudents(STU stu[], STU out[], int selected[]);
 23 // 按照学号升序排序学生信息数组
 24 void ascend(STU out[]);
 25 // 输出抽点学生信息到屏幕
 26 void output(STU out[]);
 27 // 保存抽点学生信息到文件
 28 void save(STU out[]);
 29 
 30 STU stu[MAX_NUM];
 31 int selected[SELECTION_COUNT];  //保存生成随机数的数组 
 32 STU out[SELECTION_COUNT];  //保存随机抽点的名单的一个数组 
 33 
 34 int main()
 35 {
 36     generateRandomIndices(selected);
 37     read(stu);
 38     extractSelectedStudents(stu, out, selected);
 39     ascend(out);
 40     output(out);
 41     save(out);
 42 
 43     return 0;
 44 }
 45 
 46 // 生成随机不重复的索引数组
 47 void generateRandomIndices(int selected[]) {
 48     int exists[MAX_NUM] = { 0 }; // 标记数组,初始全为0
 49     int count = 0;
 50 
 51     // 初始化随机数生成器
 52     srand(time(NULL));
 53 
 54     while (count < SELECTION_COUNT) {
 55         int random_num = rand() % MAX_NUM; // 生成0-79的随机数
 56 
 57         // 检查该随机数是否已经存在
 58         if (!exists[random_num]) {
 59             exists[random_num] = 1; // 标记为存在
 60             selected[count++] = random_num; // 保存随机数
 61         }
 62     }
 63 }
 64 
 65 // 从文件读取学生信息到数组
 66 void read(STU stu[]) {
 67     FILE* fp;
 68 
 69     // 以读的方式打开文本文件list.txt 
 70     fp = fopen("list.txt", "r");
 71 
 72     // 如果打开文件失败,输出提示信息并返回 
 73     if (fp == NULL) {
 74         printf("fail to open file to read\n");
 75         return;
 76     }
 77 
 78     for (int i = 0; i < MAX_NUM; i++) {
 79         fscanf(fp, "%ld %s %s", &stu[i].id, stu[i].name, stu[i].class);
 80     }
 81 
 82     fclose(fp);
 83 }
 84 
 85 // 根据索引数组将选中的学生信息提取出来
 86 void extractSelectedStudents(STU stu[], STU out[], int selected[]) {
 87     for (int i = 0; i < SELECTION_COUNT; i++) {
 88         out[i] = stu[selected[i]];
 89     }
 90 }
 91 
 92 // 按照学号升序排序学生信息数组
 93 void ascend(STU out[]) {
 94     for (int i = 0; i < SELECTION_COUNT - 1; i++) {
 95         for (int j = 0; j < SELECTION_COUNT - i - 1; j++) {
 96             if (out[j].id > out[j + 1].id) {
 97                 STU temp = out[j];
 98                 out[j] = out[j + 1];
 99                 out[j + 1] = temp;
100             }
101         }
102     }
103 }
104 
105 // 输出抽点学生信息到屏幕
106 void output(STU out[]) {
107    
108     printf("————————随机抽点名单-------------\n");
109     for (int i = 0; i < SELECTION_COUNT; i++) {
110         printf("%ld\t\t%s\t\t%s\n", out[i].id, out[i].name, out[i].class);
111     }
112     
113 }
114 
115 
116 
117 // 保存抽点学生信息到文件
118 void save(STU out[]) {
119 
120     char filename[13];  
121     printf("输入文件名:");
122     scanf("%s",filename) ;
123 
124     FILE* fp = fopen(filename, "w");
125     if (fp == NULL) {
126         perror("无法打开文件");
127         return;
128     }
129 
130     for (int i = 0; i < SELECTION_COUNT; i++) {
131         fprintf(fp, "%ld\t\t%s\t\t%s\n", out[i].id, out[i].name, out[i].class);
132     }
133 
134     fclose(fp);
135     printf("保存成功\n");
136 }

 

 

运行截图:

 

 

 选做代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<time.h>
  5 
  6 #define MAX_NUM 80    // 生成随机数的范围 0-79
  7 #define SELECTION_COUNT 5  // 选择的随机数个数
  8 #define N 20
  9 #define M 40
 10 
 11 typedef struct {
 12     long id;    // 学号 
 13     char name[N];     // 姓名 
 14     char class[M];  //班级 
 15 } STU;
 16 
 17 // 生成随机不重复的索引数组
 18 void generateRandomIndices(int selected[]);
 19 // 从文件读取学生信息到数组
 20 void read(STU stu[]);
 21 // 根据索引数组将选中的学生信息提取出来
 22 void extractSelectedStudents(STU stu[], STU out[], int selected[]);
 23 // 按照学号升序排序学生信息数组
 24 void ascend(STU out[]);
 25 // 输出抽点学生信息到屏幕
 26 void output(STU out[]);
 27 // 获取当前日期字符串
 28 char* getCurrentDate();
 29 // 保存抽点学生信息到文件
 30 void save(STU out[]);
 31 
 32 STU stu[MAX_NUM];
 33 int selected[SELECTION_COUNT];  //保存生成随机数的数组 
 34 STU out[SELECTION_COUNT];  //保存随机抽点的名单的一个数组 
 35 
 36 int main()
 37 {
 38     generateRandomIndices(selected);
 39     read(stu);
 40     extractSelectedStudents(stu, out, selected);
 41     ascend(out);
 42     output(out);
 43     save(out);
 44 
 45     return 0;
 46 }
 47 
 48 // 生成随机不重复的索引数组
 49 void generateRandomIndices(int selected[]) {
 50     int exists[MAX_NUM] = { 0 }; // 标记数组,初始全为0
 51     int count = 0;
 52 
 53     // 初始化随机数生成器
 54     srand(time(NULL));
 55 
 56     while (count < SELECTION_COUNT) {
 57         int random_num = rand() % MAX_NUM; // 生成0-79的随机数
 58 
 59         // 检查该随机数是否已经存在
 60         if (!exists[random_num]) {
 61             exists[random_num] = 1; // 标记为存在
 62             selected[count++] = random_num; // 保存随机数
 63         }
 64     }
 65 }
 66 
 67 // 从文件读取学生信息到数组
 68 void read(STU stu[]) {
 69     FILE* fp;
 70 
 71     // 以读的方式打开文本文件list.txt 
 72     fp = fopen("list.txt", "r");
 73 
 74     // 如果打开文件失败,输出提示信息并返回 
 75     if (fp == NULL) {
 76         printf("fail to open file to read\n");
 77         return;
 78     }
 79 
 80     for (int i = 0; i < MAX_NUM; i++) {
 81         fscanf(fp, "%ld %s %s", &stu[i].id, stu[i].name, stu[i].class);
 82     }
 83 
 84     fclose(fp);
 85 }
 86 
 87 // 根据索引数组将选中的学生信息提取出来
 88 void extractSelectedStudents(STU stu[], STU out[], int selected[]) {
 89     for (int i = 0; i < SELECTION_COUNT; i++) {
 90         out[i] = stu[selected[i]];
 91     }
 92 }
 93 
 94 // 按照学号升序排序学生信息数组
 95 void ascend(STU out[]) {
 96     for (int i = 0; i < SELECTION_COUNT - 1; i++) {
 97         for (int j = 0; j < SELECTION_COUNT - i - 1; j++) {
 98             if (out[j].id > out[j + 1].id) {
 99                 STU temp = out[j];
100                 out[j] = out[j + 1];
101                 out[j + 1] = temp;
102             }
103         }
104     }
105 }
106 
107 // 输出抽点学生信息到屏幕
108 void output(STU out[]) {
109     char* currentDate = getCurrentDate();
110     printf("————————%s抽点名单-------------\n", currentDate);
111     for (int i = 0; i < SELECTION_COUNT; i++) {
112         printf("%ld\t\t%s\t\t%s\n", out[i].id, out[i].name, out[i].class);
113     }
114     free(currentDate);  // 释放获取日期字符串时分配的内存
115 }
116 
117 // 获取当前日期字符串
118 char* getCurrentDate() {
119     // 在堆上分配内存用于存储日期字符串
120     char* timeStr = (char*)malloc(9 * sizeof(char)); // 8个字符 + 1个结束符
121     if (timeStr == NULL) {
122         return NULL; // 内存分配失败
123     }
124 
125     time_t now = time(NULL); // 获取当前时间
126     struct tm* tm_now = localtime(&now); // 将时间转为本地时间结构
127 
128     // 格式化当前日期为 YYYYMMDD
129     snprintf(timeStr, 9, "%04d%02d%02d",
130         tm_now->tm_year + 1900, // 年份从1900开始,所以要加1900
131         tm_now->tm_mon + 1,     // 月份从0开始,所以要加1
132         tm_now->tm_mday);       //
133 
134     return timeStr; // 返回指向字符串的指针
135 }
136 
137 // 保存抽点学生信息到文件
138 void save(STU out[]) {
139     char* currentDate = getCurrentDate();
140     char filename[13];  // 足够存储形如20241230.txt这样的文件名
141     snprintf(filename, 13, "%s.txt", currentDate);
142     free(currentDate);
143 
144     FILE* fp = fopen(filename, "w");
145     if (fp == NULL) {
146         perror("无法打开文件");
147         return;
148     }
149 
150     for (int i = 0; i < SELECTION_COUNT; i++) {
151         fprintf(fp, "%ld\t\t%s\t\t%s\n", out[i].id, out[i].name, out[i].class);
152     }
153 
154     fclose(fp);
155     printf("文件保存成功\n");
156 }

 

运行截图:

 

posted @ 2024-12-29 17:29  安东尼23  阅读(47)  评论(0)    收藏  举报