已排序的学生成绩文件进行插人处理。插人一个学生的3门课程成绩,程序先计算新插人学生的平均成绩,然后将它按成绩高低顺序插入,插入后不建立一个新文件。
#include<stdio.h>
#include<stdlib.h>
struct Student {
int number;
char name[10];
int score[3];
float ave;
}stu[3], stue;
int main() {
FILE* fp, * fp2;
char string[100], c;
int n = 0, t = 0;
if ((fp = fopen("1.txt", "rb")) == NULL) {
printf("未找到该文件");
exit(0);
}
scanf("%d%s%d%d%d", &stue.number, stue.name, &stue.score[0], &stue.score[1], &stue.score[2]);
stue.ave = (float)(stue.score[0] + stue.score[1] + stue.score[2]) / 3;
for (int i = 0; (fscanf(fp, "%d%s%d%d%d%f", &stu[i].number, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2], &stu[i].ave))!=0; i++) {
n++;
printf("n:%d\n");
}
printf("n:%d\n", n);
for (int j = 0; j < 3; j++) {
if (stue.ave < stu[j].ave) {
t++;
}
}
if ((fp2 = fopen("1.txt", "w")) == NULL) {
printf("未找到该文件");
exit(0);
}
for (int i = 0; i < t; i++) {
fprintf(fp2, "%d %s %d %d %d %f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
printf(" % d % s % d % d % d % f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
}
fprintf(fp2, "%d %s %d %d %d %f\n", stue.number, stue.name, stue.score[0], stue.score[1], stue.score[2], stue.ave);
printf(" % d % s % d % d % d % f\n", stue.number, stue.name, stue.score[0], stue.score[1], stue.score[2], stue.ave);
for (int i = t; i < n; i++) {
fprintf(fp2, "%d %s %d %d %d %f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
printf(" % d % s % d % d % d % f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
}
}
结果:死循环
原因:fscanf()并未读取到数据时的返回值不是0。
fread()返回值为实际读取到的文件内容的块数,到结尾返回0。
fscanf()则返回的是实际读取的数据个数,出错或者到结尾返回EOF。
修改后:
#include<stdio.h>
#include<stdlib.h>
struct Student {
int number;
char name[10];
int score[3];
float ave;
}stu[3], stue;
int main() {
FILE* fp, * fp2;
char string[100], c;
int n = 0, t = 0;
if ((fp = fopen("1.txt", "rb")) == NULL) {
printf("未找到该文件");
exit(0);
}
scanf("%d%s%d%d%d", &stue.number, stue.name, &stue.score[0], &stue.score[1], &stue.score[2]);
stue.ave = (float)(stue.score[0] + stue.score[1] + stue.score[2]) / 3;
for (int i = 0; (fscanf(fp, "%d%s%d%d%d%f", &stu[i].number, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2], &stu[i].ave)) !=EOF; i++) {
n++;
}
printf("n:%d\n", n);
for (int j = 0; j < 3; j++) {
if (stue.ave < stu[j].ave) {
t++;
}
}
if ((fp2 = fopen("1.txt", "w")) == NULL) {
printf("未找到该文件");
exit(0);
}
for (int i = 0; i < t; i++) {
fprintf(fp2, "%d %s %d %d %d %f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
printf(" % d %s % d % d % d % f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
}
fprintf(fp2, "%d %s %d %d %d %f\n", stue.number, stue.name, stue.score[0], stue.score[1], stue.score[2], stue.ave);
printf(" % d %s % d % d % d % f\n", stue.number, stue.name, stue.score[0], stue.score[1], stue.score[2], stue.ave);
for (int i = t; i < n; i++) {
fprintf(fp2, "%d %s %d %d %d %f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
printf(" %d %s %d %d % d % f\n", stu[i].number, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].ave);
}
}
结果:
看书上的答案是fread(&stu[i],sizeof(struct Student),1,fp)!=0,就认为fscanf()并未读取到数据时的返回值是0,还是基础不够扎实。