Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
fscanf!=eof铿锵编译器,异常行为_C_File_Clang - Fatal编程技术网

fscanf!=eof铿锵编译器,异常行为

fscanf!=eof铿锵编译器,异常行为,c,file,clang,C,File,Clang,我有一个我无法理解的恼人的问题 void file_count(FILE* stream,int* const num) { int temp; while((fscanf(stream,"%d",&temp))!=EOF) { (*num)++; } } 有了这个程序,我从一个文件中读取了里面的所有数字,每次我读取一个数字,计数器就会增加,这样我就可以计算文件中有多少元素 在这个文件中有6个数字,但是如果我运行这个代码,计数器会飙升到3

我有一个我无法理解的恼人的问题

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");
}
#包括
#包括
#包括
typedef char*字符串;
类型定义结构学生
{
int标志;
字符名[25];
查氏[25];
查尔宿舍[25];
国际*职等;
}
大学生
无效检查_输入(常量int argc,常量字符串*常量argv);
作废检查_文件(文件*流);
无效文件计数(文件*流,int*常量num);
无效更新学生(常量字符串*常量信息,学生*常量学生,常量整数分数,文件*流);
无效打印学生(文件*流、学生常量学生、常量整数分数);
int main(int argc,字符串argv[])
{
检查输入(argc、argv);
档案*1、*2;
字符串信息[]={“David”、“Malan”、“Mather”};
学生;
国际职系;
一个=fopen(argv[1],“r”);
检查_文件(一份);
文件计数(一级和三级);
更新学生(信息和学生,成绩,一);
fclose(一个);
二=fopen(argv[2],“w”);
检查_文件(两个);
打印学生(两个,学生,年级);
fclose(两个);
免费(学生成绩);
系统(“猫出”);
返回0;
}
无效检查_输入(常量int argc,常量字符串*常量argv)
{
如果(argc!=3)
{
printf(“\x1B[31mError:%s接受两个参数!\x1B[0m\n”,argv[0]);
退出(退出失败);
}
}
无效检查_文件(文件*流)
{
if(流==NULL)
{
printf(“\x1B[31mError:无效文件。\x1B[0m\n”);
退出(退出失败);
}
}
无效文件计数(文件*流,整数*常量)
{
内部温度;
printf(“读取文件…\n”);
while((fscanf(流、%i、&temp))!=EOF)
{
(*num)++;
}
printf(“\x1B[33m读取的值为%i\x1B[0m\n”,*num);
}
无效更新学生(常量字符串*常量信息,学生*常量学生,常量整数分数,文件*流)
{
倒带(流);
学生->成绩=malloc(成绩*sizeof(int));
strcpy(学生->姓名,信息[0]);
strcpy(学生->姓氏,信息[1]);
strcpy(学生->宿舍,信息[2]);
学生->标志=0;
对于(int i=0;igrades[i]);
}
}
无效打印学生(文件*流、学生常量学生、常量整数分数)
{
printf(“写入文件..\n”);
fprintf(流,“%i%s%s%s”,学生.标志,学生.姓名,学生.姓氏,学生.宿舍);

对于(inti=0;i您的代码是危险的,因为错误的文件将其发送到无限循环中

使用
%d
fscanf
找到一个不能解释为
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
,或者在
file\u count
中进入循环之前添加
*num=0
,您的代码是危险的,因为不正确的文件将其发送到无限循环中

使用
%d
fscanf
找到一个不能解释为
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
,或者在
file\u count
中进入循环之前添加
*num=0
当前的ISO C标准将
fscanf()
的返回值定义为

如果在第一次转换(如果有的话)完成之前发生输入失败,则fscanf函数返回宏EOF的值。否则,该函数返回分配的输入项的数量,如果早期匹配失败,该数量可以小于提供的数量,甚至为零

ISO-C标准的逐字引用(没有可用的公共链接,该标准不是公共AFAIK)

如果有数据要读取,但无法成功匹配该数据,则此函数将返回0。如果由于您正在读取的流处于EOF状态或存在另一个读取错误而没有数据要读取,则仅返回EOF(通常为
-1

如果你有这样一个文件:

23 a 57

循环永远不会终止。在第一次扫描时,它将读取23并返回1(一个值匹配)。在下一次调用时,它将返回0,因为
a
无法与整数匹配。但是,它也不会将文件指针移到
a
之外。因此,在下一次调用时,它将再次尝试匹配
a
,并且将再次失败。这将持续不断。

当前的ISO C标准将
fscanf()
的返回值定义为

如果在第一次转换(如果有的话)完成之前发生输入故障,fscanf函数将返回宏EOF的值。否则,该函数将返回分配的输入项的数量,该数量可以小于提供的数量,甚至为零,