【发布时间】:2021-06-11 20:07:50
【问题描述】:
下面的代码取自有关学生的文件数据,并为指定组的第一个科目的成绩添加一个点。但是,在执行此操作的 while 循环中, fseek(binaryFile, 0, 1) 可防止循环成为无限循环。我发现 fseek(binaryFile, 0, 1) 用于从写入模式转到读取模式,但我不明白它是如何工作的以及它如何防止无限循环。
#include <stdio.h>
typedef struct
{
int identificationNumber;
char name[30];
int year;
int group;
int numberOfGrades;
int grades[15];
} Student;
void main()
{
FILE *binaryFile;
Student student;
char fileName[20];
printf("Enter the binary file name (.dat): ");
gets(fileName);
binaryFile = fopen(fileName, "rb+");
if (!binaryFile)
{
printf("The file could not be opened");
}
else
{
int groupNumberWanted;
printf("Enter the group number: ");
scanf("%d", &groupNumberWanted);
while (!feof(stdin))
{
rewind(binaryFile);
fread(&student, sizeof(Student), 1, binaryFile);
int doesGroupExist = 0;
while (!feof(binaryFile))
{
if (groupNumberWanted == student.group)
{
doesGroupExist = 1;
if (student.grades[0] < 10)
{
student.grades[0] = student.grades[0] + 1;
}
fseek(binaryFile, ftell(binaryFile) - sizeof(Student), 0);
fwrite(&student, sizeof(Student), 1, binaryFile);
fseek(binaryFile, 0, 1); // without this line, the while loop is an infinite loop
}
fread(&student, sizeof(Student), 1, binaryFile);
}
if (doesGroupExist == 0)
{
printf("The group wasn't found.\n");
}
printf("Enter the group number: ");
scanf("%d", &groupNumberWanted);
}
fclose(binaryFile);
}
}
【问题讨论】:
-
feof不是用于检查文件是否已到达末尾。读/写函数的返回值通过返回NULL字符串、EOF或指示读取了零字节来实现。 -
为了清楚起见,请使用常量
SEEK_SET|CUR|END,我们很多人都不会记住它的数值。 (我没有。) -
请参阅man page 了解更多信息,上面写着“当您从写入切换到读取时,您必须使用对 fflush 或文件定位函数的干预调用。” i> 假设的“无限循环”大概是不这样做的结果。
-
至于你的问题:如果
"r+"和"w+"模式希望你在改变模式时进行定位,那就是这样做的。如果你不这样做,然后在阅读时没有得到正确的结果,那是你的错。没有什么要理解的,这只是事情在幕后实现的方式。 (一般来说,我看到实现数据库的初学者经常使用的"+"模式,狂野的fseek跳跃等等。我认为最好有两个数据库加载/保存函数并在内存中进行所有操作.)
标签: c file while-loop fseek