文件操作作业
目录:
第一种
这种相当于省去了从 ==结构体数组== 到 ==单链表== 的过程(省去了 create() 函数),直接创建了链表。
可以自行删除 output() 函数。
C |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
// 定义学生结构体
struct Student {
char name[10];
int num;
int age;
char addr[15];
struct Student* next; // 链表指针
};
// 函数声明
void save(struct Student* head);
void output(struct Student*);
int main() {
// 创建链表头节点
struct Student* head = NULL;
struct Student* current = NULL;
// 从键盘输入学生数据并创建链表
printf("请输入学生信息:\n\n");
for (int i = 0; i < SIZE; ++i) {
// 创建新节点
struct Student* temp = (struct Student*)malloc(sizeof(struct Student));
// 从键盘输入学生数据
printf("学生序号 --%d--:\n", i + 1);
printf("姓名: ");
scanf("%s", temp->name);
printf("学号: ");
scanf("%d", &temp->num);
printf("年龄: ");
scanf("%d", &temp->age);
printf("住址: ");
scanf("%s", temp->addr);
printf("\n");
// 将新节点插入链表
temp->next = NULL;
if (head == NULL) {
head = temp;
}
else {
current->next = temp;
}
current = temp;
}
// 保存学生数据到磁盘文件
save(head);
printf("保存成功.\n\n");
//打开文件并输出信息
output(head);
// 释放链表内存
struct Student* temp;
while (head != NULL) {
temp = head;
head = head->next;
free(temp);
}
return 0;
}
void save(struct Student* head) {
// 打开文件以写入二进制数据
FILE* file = fopen("student_data.dat", "wb");
if (file == NULL) {
fprintf(stderr, "无法打开文件进行写入.\n");
exit(1);
}
// 将链表中的学生数据写入文件
// 用这个 while 也可以,用下面的 for 也行
//while (head != NULL) {
// fwrite(head, sizeof(struct Student), 1, file);
//}
for (int i = 0; i < SIZE; i++) {
if (fwrite(head, sizeof(struct Student), 1, file) == 1) {
head = head->next;
}
else {
printf("文件写入错误\n");
}
}
// 关闭文件
fclose(file);
}
void output(struct Student* head) {
struct Student read[SIZE];
FILE* fp;
if ((fp = fopen("student_data.dat", "rb")) == NULL)
{
printf("无法打开文件\n");
exit(0);
}
printf("以下为从文件中读取的数据:\n\n");
for (int i = 0; i < SIZE; i++)
{
fread(&read[i], sizeof(struct Student), 1, fp);
printf("学生序号 --%d--:\n", i + 1);
printf("姓名\t学号\t年龄\t住址\n");
printf("%-7s %-7d %-7d %-7s\n",
read[i].name, read[i].num,
read[i].age, read[i].addr);
printf("\n");
}
fclose(fp);
return 0;
}
|
第二种
这种就是正常的创建 ==结构体数组== ,然后用 create() 函数 创建 ==链表== 。
可以自行删除 output() 函数。
C |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
// 定义学生结构体
struct Student {
char name[10];
int num;
int age;
char addr[15];
struct Student* next; // 链表指针
};
// 函数声明
void input(struct Student stu[]);
struct Student* create(struct Student*);
void save(struct Student*);
void output(struct Student*);
int main() {
struct Student stu[SIZE];
struct Student* h;
// 从键盘输入学生数据
input(stu);
// 创建链表
h = create(stu);
// 保存学生数据到磁盘文件
save(h);
printf("保存成功.\n\n");
// 输出数据,查看是否成功保存
output(h);
return 0;
}
// 输入学生信息到数组,n为学生个数
void input(struct Student stu[]) {
printf("请输入学生信息:\n\n");
for (int i = 0; i < SIZE; ++i) {
// 从键盘输入学生数据
printf("学生序号 --%d--:\n", i + 1);
printf("姓名: ");
scanf("%s", stu[i].name);
printf("学号: ");
scanf("%d", &stu[i].num);
printf("年龄: ");
scanf("%d", &stu[i].age);
printf("住址: ");
scanf("%s", stu[i].addr);
printf("\n");
}
}
struct Student* create(struct Student stu[]) {
struct Student* head = NULL; // 头指针初始化为空
struct Student* tail = NULL; // 初始化尾指针为NULL
struct Student* temp;
for (int i = 0; i < SIZE; i++) {
temp = (struct Student*)malloc(sizeof(struct Student)); // 为新节点分配内存
if (temp == NULL) {
printf("内存分配失败\n");
exit(1);
}
// 将数组中的学生信息复制到新节点
strcpy(temp->name, stu[i].name);
temp->num = stu[i].num;
temp->age = stu[i].age;
strcpy(temp->addr, stu[i].addr);
temp->next = NULL;
if (head == NULL) {
head = temp; // 如果是第一个节点,直接作为头节点
}
else {
tail->next = temp; // 否则加入到链表的尾部
}
tail = temp; // 更新尾指针
}
return head; // 返回头指针
}
void save(struct Student* head) {
// 打开文件以写入二进制数据
FILE* file = fopen("student_data.dat", "wb");
if (file == NULL) {
fprintf(stderr, "无法打开文件进行写入.\n");
exit(1);
}
// 将链表中的学生数据写入文件
//// 用这个 while 也可以,用下面的 for 也行
//while (head != NULL) {
// fwrite(head, sizeof(struct Student), 1, file);
// head = head->next;
//}
for (int i = 0; i < SIZE; i++) {
if (fwrite(head, sizeof(struct Student), 1, file) == 1) {
head = head->next;
}
else {
printf("文件写入错误\n");
}
}
// 关闭文件
fclose(file);
}
void output(struct Student* head) {
struct Student read[SIZE];
FILE* fp;
if ((fp = fopen("student_data.dat", "rb")) == NULL)
{
printf("无法打开文件\n");
exit(0);
}
printf("以下为从文件中读取的数据:\n\n");
for (int i = 0; i < SIZE; i++)
{
fread(&read[i], sizeof(struct Student), 1, fp);
printf("学生序号 --%d--:\n", i + 1);
printf("姓名\t学号\t年龄\t住址\n");
printf("%-7s %-7d %-7d %-7s\n",
read[i].name, read[i].num,
read[i].age, read[i].addr);
printf("\n");
}
fclose(fp);
return 0;
}
|
load() 函数版本
这个你要是想测试的话,就创建 stu.list 文件进行测试,有以下三种情况
-
无 stu.list 文件,显示 "无法载入文件" 。
-
有 stu.list 文件,但其中无数据或数据错误(题目要求是二进制数据),显示 "文件读取错误" 。
-
有 stu.list 文件,且其中数据正常,正常读取数据。
但是这儿关于第三种情况,也就是正常情况,有一些东西东西需要说明:
-
最简单的方法就是正常运行前两种的代码,然后生成 student_data.dat 文件,再将该文件重命名为 stu.list 。
-
请在资源管理器中进行设置,使 文件后缀名 能正常显示。否则很可能出现以下问题,你将一个文件重命名为 stu.list ,然而实际上它是 stu.list.txt 也就是说它其实是一个 .txt 文件。
C |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
// 定义学生结构体
struct Student {
char name[10];
int num;
int age;
char addr[15];
struct Student* next; // 链表指针
};
// 函数声明
void load(struct Student stu[]);
struct Student* create(struct Student*);
void save(struct Student*);
void output(struct Student*);
int main() {
struct Student stu[SIZE];
struct Student* h;
//载入数据
load(stu);
// 创建链表
h = create(stu);
// 保存学生数据到磁盘文件
save(h);
printf("保存成功.\n\n");
// 输出数据
output(h);
return 0;
}
void load(struct Student stu[])
{
FILE* fp;
if ((fp = fopen("stu.list", "rb")) == NULL)
{
printf("无法载入文件\n");
exit(1);
}
for (int i = 0; i < SIZE; i++) {
if (fread(&stu[i], sizeof(struct Student), 1, fp) != 1)
{
if (feof(fp))
{
fclose(fp);
printf("文件读取错误\n");
exit(1);
}
}
}
fclose(fp);
}
struct Student* create(struct Student stu[]) {
struct Student* head = NULL; // 头指针初始化为空
struct Student* tail = NULL; // 初始化尾指针为NULL
struct Student* temp;
for (int i = 0; i < SIZE; i++) {
temp = (struct Student*)malloc(sizeof(struct Student)); // 为新节点分配内存
if (temp == NULL) {
printf("内存分配失败\n");
exit(1);
}
// 将数组中的学生信息复制到新节点
strcpy(temp->name, stu[i].name);
temp->num = stu[i].num;
temp->age = stu[i].age;
strcpy(temp->addr, stu[i].addr);
temp->next = NULL;
if (head == NULL) {
head = temp; // 如果是第一个节点,直接作为头节点
}
else {
tail->next = temp; // 否则加入到链表的尾部
}
tail = temp; // 更新尾指针
}
return head; // 返回头指针
}
void save(struct Student* head) {
// 打开文件以写入二进制数据
FILE* file = fopen("student_data.dat", "wb");
if (file == NULL) {
fprintf(stderr, "无法打开文件进行写入.\n");
exit(1);
}
// 将链表中的学生数据写入文件
//// 用这个 while 也可以,用下面的 for 也行
//while (head != NULL) {
// fwrite(head, sizeof(struct Student), 1, file);
// head = head->next;
//}
for (int i = 0; i < SIZE; i++) {
if (fwrite(head, sizeof(struct Student), 1, file) == 1) {
head = head->next;
}
else {
printf("文件写入错误\n");
}
}
// 关闭文件
fclose(file);
}
void output(struct Student* head) {
struct Student read[SIZE];
FILE* fp;
if ((fp = fopen("student_data.dat", "rb")) == NULL)
{
printf("无法打开文件\n");
exit(0);
}
printf("以下为从文件中读取的数据:\n\n");
for (int i = 0; i < SIZE; i++)
{
fread(&read[i], sizeof(struct Student), 1, fp);
printf("学生序号 --%d--:\n", i + 1);
printf("姓名\t学号\t年龄\t住址\n");
printf("%-7s %-7d %-7d %-7s\n",
read[i].name, read[i].num,
read[i].age, read[i].addr);
printf("\n");
}
fclose(fp);
return 0;
}
|