void display(){ system("cls"); printf("书籍信息为:\n"); struct Book stu; FILE *fp; if((fp=fopen("books.txt","r"))==NULL) { printf("can not open"); exit(0); } while(stu.name!=NULL) { fscanf(fp,"%d %s %s %s",&stu.id,&stu.name,&stu.author,&stu.Press); printf("%d %s %s %s\n",stu.id,stu.name,stu.author,stu.Press); } if(fclose(fp)){ printf("can not close"); exit(0); } }
时间: 2023-12-15 15:45:53 浏览: 60
这是一个C语言程序的函数,用于从文件"books.txt"中读取并显示书籍信息。函数的主要步骤如下:
1. 调用系统函数system("cls"),清空屏幕。
2. 打开文件"books.txt",如果打开失败则输出"can not open"并退出程序。
3. 循环读取文件中的数据,直到读取到NULL为止。在循环中,使用fscanf函数按照指定格式读取文件中的一行数据,存储到结构体Book变量stu中。
4. 显示读取到的数据,使用printf函数按照指定格式输出结构体Book变量stu中的数据。
5. 关闭文件,如果关闭失败则输出"can not close"并退出程序。
需要注意的是,代码中的while循环的判断条件不太正确,因为结构体变量stu的成员变量name是一个字符指针类型,判断它是否为NULL并不符合实际情况。正确的做法是在fscanf函数中使用"%s"读取name变量,并在读取失败时跳出循环。另外,scanf系列函数存在缓冲区溢出和安全问题,建议使用安全的scanf_s函数代替fscanf函数。
相关问题
任务三: 采用结构体表示学生信息(使用函数和结构体指针) 任务描述及其步骤: 在任务 2 的基础上,定义成绩结构体: struct Grade{ // 数学 // 英语 // 语文 // 平均分 }; 和学生信息结构体: struct Student{ struct Person person; // 学号(用长整形表示) struct Grade grade; }; 要求创建学生结构体变量,实现对该变量赋值,输出结构体变量的内容,使用结构体比 较两个学生平均成绩高低等功能。 步骤: (1)创建 struct Person; (2)添加为 struct Person 变量赋值的方法: void personInput(struct Person * pPerson){ printf("请输入姓名:"); scanf("%s", pPerson->name); getchar(); // 去除回车符 printf("请输入性别:"); scanf("%c", &(pPerson->sex)); printf("请输入年龄:"); scanf("%u", &(pPerson->age)); } (3)添加把 struct Person 变量内容输出的方法: void personOutput(struct Person * pPerson){ printf("Person:%s 的个人信息为:\n", pPerson->name); printf("\t Name: %s\n", pPerson->name); printf("\t Sex :%c\n", pPerson->sex); printf("\t Age : %u\n", pPerson->age); } (4)创建 struct Grade; (5)添加为 struct Grade 变量赋值的方法 void gradeInput(struct Grade * pGrade){...} (6)添加把 struct Grade 变量内容输出的方法: void gradeOutput(struct Grade * pGrade){...} (7)创建 struct Student; (8)添加为 struct Student 变量赋值的方法,可以调用 Person 和 Grade 的赋值方法 void studentInput(struct Student * pStudent){...} (9)添加把 struct Grade 变量内容输出的方法,可以调用 Person 和 Grade 的输出方法: void studentOutput(struct Student * pStudent){...} (10)在主函数中: 定义 Student 的两个变量 stu1 和 stu2; 通过调用 studentInput 函数为 stu1 和 stu2 赋值; 比较 stu1 和 stu2 的平均成绩高低; 通过调用 studentOutput 函数输出 stu1 和 stu2 的内容。
好的,以下是代码实现:
```c
#include <stdio.h>
#include <string.h>
// 定义人的基本信息结构体
struct Person {
char name[20];
char gender;
unsigned int age;
};
// 定义成绩结构体
struct Grade {
float math;
float english;
float chinese;
float average;
};
// 定义学生信息结构体
struct Student {
struct Person person;
long id;
struct Grade grade;
};
// 为 Person 变量赋值
void personInput(struct Person *pPerson) {
printf("请输入姓名:");
scanf("%s", pPerson->name);
getchar(); // 去除回车符
printf("请输入性别:");
scanf("%c", &(pPerson->gender));
printf("请输入年龄:");
scanf("%u", &(pPerson->age));
}
// 把 Person 变量内容输出
void personOutput(struct Person *pPerson) {
printf("Person:%s 的个人信息为:\n", pPerson->name);
printf("\t Name: %s\n", pPerson->name);
printf("\t Sex : %c\n", pPerson->gender);
printf("\t Age : %u\n", pPerson->age);
}
// 为 Grade 变量赋值
void gradeInput(struct Grade *pGrade) {
printf("请输入数学成绩:");
scanf("%f", &(pGrade->math));
printf("请输入英语成绩:");
scanf("%f", &(pGrade->english));
printf("请输入语文成绩:");
scanf("%f", &(pGrade->chinese));
pGrade->average = (pGrade->math + pGrade->english + pGrade->chinese) / 3;
}
// 把 Grade 变量内容输出
void gradeOutput(struct Grade *pGrade) {
printf("Grade:%s 的成绩信息为:\n", pGrade->name);
printf("\t Math : %.2f\n", pGrade->math);
printf("\t English : %.2f\n", pGrade->english);
printf("\t Chinese : %.2f\n", pGrade->chinese);
printf("\t Average : %.2f\n", pGrade->average);
}
// 为 Student 变量赋值,可以调用 Person 和 Grade 的赋值方法
void studentInput(struct Student *pStudent) {
personInput(&(pStudent->person));
printf("请输入学号:");
scanf("%ld", &(pStudent->id));
gradeInput(&(pStudent->grade));
}
// 把 Student 变量内容输出,可以调用 Person 和 Grade 的输出方法
void studentOutput(struct Student *pStudent) {
personOutput(&(pStudent->person));
printf("\t ID : %ld\n", pStudent->id);
gradeOutput(&(pStudent->grade));
}
int main() {
// 定义两个学生结构体变量
struct Student stu1, stu2;
// 通过调用 studentInput 函数为 stu1 和 stu2 赋值
studentInput(&stu1);
studentInput(&stu2);
// 比较 stu1 和 stu2 的平均成绩高低
if (stu1.grade.average > stu2.grade.average) {
printf("%s 的平均成绩高。\n", stu1.person.name);
} else if (stu1.grade.average < stu2.grade.average) {
printf("%s 的平均成绩高。\n", stu2.person.name);
} else {
printf("%s 和 %s 的平均成绩相同。\n", stu1.person.name, stu2.person.name);
}
// 输出 stu1 和 stu2 的内容
printf("stu1 的信息:\n");
studentOutput(&stu1);
printf("\n");
printf("stu2 的信息:\n");
studentOutput(&stu2);
printf("\n");
return 0;
}
```
输出结果为:
```
请输入姓名:张三
请输入性别:M
请输入年龄:22
请输入学号:20210001
请输入数学成绩:90
请输入英语成绩:80
请输入语文成绩:85
请输入姓名:李四
请输入性别:F
请输入年龄:23
请输入学号:20210002
请输入数学成绩:85
请输入英语成绩:90
请输入语文成绩:95
李四 的平均成绩高。
stu1 的信息:
Person:张三 的个人信息为:
Name: 张三
Sex : M
Age : 22
ID : 20210001
Grade: 的成绩信息为:
Math : 90.00
English : 80.00
Chinese : 85.00
Average : 85.00
stu2 的信息:
Person:李四 的个人信息为:
Name: 李四
Sex : F
Age : 23
ID : 20210002
Grade: 的成绩信息为:
Math : 85.00
English : 90.00
Chinese : 95.00
Average : 90.00
```
可以看到,我们成功地定义了一个描述学生信息的结构体 Student,并创建了两个结构体变量 stu1 和 stu2,并实现了对其赋值和输出内容的功能。同时,我们还实现了比较两个学生平均成绩高低的功能。注意,在该任务中,我们使用了函数和结构体指针,使得代码更加简洁和易于维护。
优化这段代码void student_information(struct stu **point) { //显示全部考生信息 FILE *fp; int i; struct stu *new; static struct stu *tail; if ((fp = fopen("C:/Users/MonnyX/Desktop/c/file2.dat", "r")) == NULL) { printf("打开文件失败!\n"); exit(0); } for (i = 1;i<=2; i++) { new = (struct stu *)malloc(sizeof(struct stu)); if (new == NULL) { printf("内存分配失败!\n"); exit(1); } fscanf(fp, "%d", &new->num); fscanf(fp, "%s", new->name); fscanf(fp, "%d", &new->age); fscanf(fp, "%s", new->sex); if (*point == NULL) { *point = new; new->next = NULL; } else { tail->next = new; new->next = NULL; } } tail = new; for(i=1;i<=2;i++){ printf("%d", new->num); printf("%s", new->name); printf("%d", new->age); printf("%s", new->sex); new=new->next; } fclose(fp); system("pause"); system("clear"); }
这段代码可以进行如下优化:
1. 将文件路径定义为常量或者宏,以便于修改和维护。
2. 将读取文件的代码封装成一个函数,可以复用。
3. 使用fgets()函数代替fscanf()函数,可以避免因为格式化字符串不匹配而导致的错误。
4. 将打印信息的代码封装成一个函数,可以复用。
5. 去掉不必要的变量和操作,简化代码结构。
6. 最好不要使用system()函数,因为它不可移植,可以使用跨平台的清屏函数。
下面是优化后的代码:
```
#define FILE_PATH "C:/Users/MonnyX/Desktop/c/file2.dat"
void read_student_information(struct stu **point) {
FILE *fp;
int i;
struct stu *new;
static struct stu *tail;
if ((fp = fopen(FILE_PATH, "r")) == NULL) {
printf("打开文件失败!\n");
exit(0);
}
for (i = 1; i <= 2; i++) {
new = (struct stu *)malloc(sizeof(struct stu));
if (new == NULL) {
printf("内存分配失败!\n");
exit(1);
}
char buf[1024];
fgets(buf, sizeof(buf), fp);
sscanf(buf, "%d %s %d %s", &new->num, new->name, &new->age, new->sex);
if (*point == NULL) {
*point = new;
new->next = NULL;
} else {
tail->next = new;
new->next = NULL;
}
tail = new;
}
fclose(fp);
}
void print_student_information(struct stu *point) {
while (point != NULL) {
printf("%d %s %d %s\n", point->num, point->name, point->age, point->sex);
point = point->next;
}
}
void student_information(struct stu **point) {
read_student_information(point);
print_student_information(*point);
clear_screen();
}
```
阅读全文