我有一个我无法理解的加重问题,
void file_count(FILE* stream,int* const num)
{
int temp;
while((fscanf(stream,"%d",&temp))!=EOF)
{
(*num)++;
}
}
通过这个程序,我从一个文件中读取其中包含所有数字的信息,并且我花了一个数字计数器增加,所以我可以计算文件中有多少元素。
在这个文件中有6个数字,但是如果我运行这个代码,计数器就会飙升到32777 ...... 如果我用gcc编译它,没有问题,计数器是6按预期。这是一个铿锵的错误吗?这是我不知道的功能吗?
该文件包含:
22 30 30 21 25 29
整个代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* string;
typedef struct student
{
int flag;
char name[25];
char surname[25];
char dorm[25];
int* grades;
}
Student;
void check_input(const int argc,const string* const argv);
void check_file(FILE* stream);
void file_count(FILE* stream,int* const num);
void update_student(const string* const infos,Student* const student,const int grades,FILE* stream);
void print_student(FILE* stream,Student const student,const int grades);
int main(int argc, string argv[])
{
check_input(argc,argv);
FILE* one,* two;
string info[]={"David","Malan","Mather"};
Student student;
int grades;
one=fopen(argv[1],"r");
check_file(one);
file_count(one,&grades);
update_student(info,&student,grades,one);
fclose(one);
two=fopen(argv[2],"w");
check_file(two);
print_student(two,student,grades);
fclose(two);
free(student.grades);
system("cat out");
return 0;
}
void check_input(const int argc,const string* const argv)
{
if(argc!=3)
{
printf("\x1B[31mError: %s takes two arguments!\x1B[0m\n",argv[0]);
exit(EXIT_FAILURE);
}
}
void check_file(FILE* stream)
{
if(stream==NULL)
{
printf("\x1B[31mError:invalid file.\x1B[0m\n");
exit(EXIT_FAILURE);
}
}
void file_count(FILE* stream,int* const num)
{
int temp;
printf("reading file...\n");
while((fscanf(stream,"%i",&temp))!=EOF)
{
(*num)++;
}
printf("\x1B[33mthe value read were %i\x1B[0m\n",*num);
}
void update_student(const string* const infos,Student* const student,const int grades,FILE* stream)
{
rewind(stream);
student->grades=malloc(grades*sizeof(int));
strcpy(student->name,infos[0]);
strcpy(student->surname,infos[1]);
strcpy(student->dorm,infos[2]);
student->flag=0;
for(int i=0;i<grades;i++)
{
fscanf(stream,"%i",&student->grades[i]);
}
}
void print_student(FILE* stream,Student const student,const int grades)
{
printf("Writing to file..\n");
fprintf(stream,"%i %s %s %s ",student.flag,student.name,student.surname,student.dorm);
for(int i=0;i<grades;i++)
{
fprintf(stream,"%i ",student.grades[i]);
}
printf("\x1B[32mFile successfully written..\x1B[0m\n");
}
答案 0 :(得分:4)
您的代码很危险,因为不正确的文件会将其发送到无限循环中。
fscanf
%d
找到无法解释为int
的输入后,该函数返回零,而不会消耗输入。因此,循环永远不会达到EOF
。
只要输入被消耗,您就可以通过循环解决此问题:
while(fscanf(stream,"%d",&temp) == 1) {
...
}
现在,如果计数正确与否,您需要一种与呼叫者通信的方法。你可以通过在达到EOF
时返回一个来做到这一点,否则为零:
int file_count(FILE* stream,int* const num) {
int temp, last;
while((last = fscanf(stream,"%d",&temp)) == 1) {
(*num)++;
}
return last == EOF;
}
我尝试使用
fscaf==1
它仍然达到32777
这是因为您没有在调用者中初始化grades
。您应该将其定义为int grades = 0
,或在*num = 0
中输入循环之前添加file_count
。
答案 1 :(得分:0)
当前的ISO C标准将fscanf()
的返回值定义为
如果在第一次转换(如果有)完成之前发生输入故障,fscanf函数将返回宏EOF的值。否则,该函数返回分配的输入项的数量,如果早期匹配失败,则可以少于提供的数量,甚至为零。
ISO-C标准的逐字引用(没有可用的公共链接,标准不是公开的AFAIK)
如果有要读取的数据,但该数据无法成功匹配,则此函数将返回0.如果没有要读取的数据,它将仅返回EOF(通常为-1
)因为流是您的正在读取处于EOF状态或有另一个读取错误。
所以如果你有这样的文件:
23 a 57
循环永远不会终止。在第一次扫描时,它将读取23并返回1(一个值匹配)。在下一次调用时,它将返回0,因为a
无法与整数匹配。然而,它也不会将文件指针移到a
之外。因此,在下一次调用时,它会再次尝试匹配a
,它将再次失败。这种情况持续不断。