为什么此代码只打印文件的第一行?

Why does this code only print the first line of the file?

提问人:Mohammad Harouak 提问时间:2/22/2021 更新时间:2/23/2021 访问量:160

问:

任职要求:

编写一个 C 程序,按顺序执行以下任务:

  • 最初在执行窗口中显示文件的内容
  • 要求用户提供 ID,在文件中搜索 ID,然后按以下格式显示消息(在执行窗口中):ID 为 ......... 的学生对应于...................谁主修.................. 当您在输出中打印学生的姓名时,请勿打印“_”!

问题: 它只输出文件中的第一行(又名第一个学生信息),之后甚至不要求提供学生证。

代码:

#include <stdio.h>
#include <string.h>
typedef struct {
    int ID;
    char Last_name[30], First_name[30], major[30];
} Class;
int search_for_student(int ID_to_search, Class students[22]) {
    int i;
    for (i = 0; i < 22; i++) {
        if (students[i].ID == ID_to_search)
            return i;
    }
    return -101;
}
void main(void) {
    char line[100];
    int  ID_to_search, i, index, j;
    Class students[22];
    FILE* infp;
    infp = fopen("Section_06.txt", "r");
    if (infp == NULL) {
        printf("File unexistant!\n");
    }
    else {
        for (i = 0; i < 22; i++) {
            fscanf(infp, "%d", students[i].ID);
            printf("%d", students[i].ID);
            fscanf(infp, "%s", students[i].Last_name);
            for (j = 0; j < strlen(students[i].Last_name); j++) {
                if (students[i].Last_name[j] == '_')
                    students[i].Last_name[j] = ' ';
            }
            printf("%s", students[i].Last_name);
            fscanf(infp, "%s", students[i].First_name);
            for (j = 0; j < strlen(students[i].First_name); j++) {
                if (students[i].First_name[j] == '_')
                    students[i].First_name[j] = ' ';
            }
            printf("%s", students[i].First_name);
            fgets(students[i].major, 30, infp);
            printf("%s", students[i].major);
        }
        printf("Enter an ID: ");
        scanf("%d", &ID_to_search);
        index = search_for_student(ID_to_search, students);
        if (index == -101)
            printf("Student not found!");
        else {
            printf("Student with ID: %d corresponds to %s %s who is majoring in %s.", students[index].ID, students[index].First_name, students[index].Last_name, students[index].major);
        }
    }
    fclose(infp);
}
C 文件 结构

评论

3赞 Craig Estey 2/22/2021
编辑您的问题,并在此处的单独代码块中发布一些具有代表性的输入数据。
0赞 Robert Harvey 2/22/2021
我会从学习一种可行的方法来读取文件开始。有关代表性示例,请参阅此处
0赞 user3629249 2/23/2021
关于:如果你的编译器允许这个语句,那么它就是一个非编译器!它们只有两个有效的签名:和void main(void) {main()int main( void )int main( int argc, char *argv[] )
0赞 user3629249 2/23/2021
关于这样的语句:这是将无符号值与有符号值进行比较。( 是 a 和 函数: 返回 a 是无符号的)这仅适用于较小的正值for (j = 0; j < strlen(students[i].Last_name); j++) {jintstrlen()size_t
0赞 user3629249 2/23/2021
OT:发布的代码包含几个“神奇”数字:即 22、30、100。“神奇”数字使代码更难理解、调试等。建议使用语句或语句为这些“神奇”数字提供有意义的名称,然后在整个代码中使用这些有意义的名称。#defineenum

答:

0赞 Justin Christian 2/22/2021 #1

你错过了这一行:&

fscanf(infp, "%d", students[i].ID);

更改为:

fscanf(infp, "%d", &students[i].ID);
0赞 user3629249 2/23/2021 #2

关于:

问题:它只输出文件中的第一行(又名第一个学生信息),之后甚至不要求提供学生证。

感兴趣的代码是

    printf("Enter an ID: ");
    scanf("%d", &ID_to_search);
    index = search_for_student(ID_to_search, students);
    
    if (index == -101)
        printf("Student not found!");
    else {
        printf("Student with ID: %d corresponds to %s %s who is majoring in %s.", students[index].ID, students[index].First_name, students[index].Last_name, students[index].major);
    } 
}  // end if/else, not the end of a `for() loop

请注意,上面的代码是“else”代码块的结尾,而不是循环的一部分,因此只会执行一次for()

此外,如果要输入的学生少于 22 人,则调用将返回 EOF,而不是更新任何学生信息。您确定输入文件实际上包含 22 个学生信息实例吗?它甚至包含 1 个以上的学生信息实例吗?fscanf()

而不是使用硬编码计数 22,用于:

for (i = 0; i < 22; i++) 
    {
        fscanf(infp, "%d", students[i].ID);

建议将第一次调用的返回值用于类似于:fscanf()

i = 0;
while( fscanf(infp, "%d", students[i].ID) != EOF )
{
    ....
    i++;
} 
1赞 Paul Yang 2/23/2021 #3

有几点:

  1. main 应该返回 int

  2. fscanf(info, “%d”, &students[I].ID);“&”已被遗漏。

  3. 文件读取循环

    for (i = 0; i < 22; i++)

不好。

while(fgets(buff, sizeof(buff), infp)!=NULL){
}

应该更好。该文件可能包含或多或少的行;

  1. 将 fscanf 与 GET 结合使用并不好。请使用 fgets 读取 LINE,使用 sscanf 或 strtok 获取字段。