如何使用fscanf将大量输入从文件转换为结构体。 ANSI C89(90)

问题描述:

我在我的程序中遇到了一些代码问题。我需要读取一个文件并将其内容逐行放入结构中。该文件大约有800行,当我尝试打印我的结构,它现在应该包含文件的内容时,它只会打印大约30行,因为它们应该是。其余的提交错误或格式错误。这是我现在的功能,我简单地称它为主。我不确定什么是错,但也许它与我的malloc调用有关?如何使用fscanf将大量输入从文件转换为结构体。 ANSI C89(90)

void read_file(void){ 
int lines = count_lines(); /*function to count amount of lines in file*/ 
FILE *file; 
int i = 0; 
char filename[] = "race.txt"; 
file = fopen(filename, "r"); 
race_info *race = malloc(sizeof(race_info)); 
if (file != NULL) { 
    while (i < lines) { 
     fscanf(file, " %[A-Za-z]s %[A-Za-z]s %[A-Z]s %d %[A-Z]s %[A-Z]s %d %d", 
       race[i].race_name, 
       race[i].name, 
       race[i].lastname, 
       &race[i].age, 
       race[i].team, 
       race[i].country, 
       &race[i].position, 
       &race[i].time); 
     i++; 
    } 
} 
else { 
    perror(filename); //print the error message 
} 
for (i = 0; i < lines; i++) { 
    printf("%s %s %s %d %s %s %d %d", 
      race[i].race_name, 
      race[i].name, 
      race[i].lastname, 
      race[i].age, 
      race[i].team, 
      race[i].country, 
      race[i].position, 
      race[i].time); 
} 
fclose(file); 
} 

的结构是设置如下:

#define MAX_CHAR 100 



struct race_info{ 
    char race_name[MAX_CHAR]; 
    char name[MAX_CHAR]; 
    char lastname[MAX_CHAR]; 
    int age; 
    char team[MAX_CHAR]; 
    char country[MAX_CHAR]; 
    int position; 
    int time; 
}; 
typedef struct race_info race_info; 

从文件中的行是设置为:

RaceName    "Name LASTNAME"        AGE TEAM Country  Position  TIME 

的目标是打印的结构,让所有800线用与文件相同的格式打印。但是打印时,它只能打印大约200行,并且它不会从文件开始到结束,而是从中间取走内容。许多行也有错误的格式。

example of running program

+0

请提供输入和输出示例。 count_lines()是什么?寻求调试帮助的问题(“为什么这个代码不工作?”)必须包含所需的行为,特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建[mcve]。 – Stargateur

+1

您需要检查'fscanf'的返回值,并在失败时执行一些操作。如代码所示,如​​果其中任何一个调用失败,由于意外格式化的输入,它将会“卡住”在那里,尝试和未能读取相同的不正确输入,从而无法访问文件的其余部分。 –

+1

像'%[A-Za-z] s'这样的格式可能是错误的。我怀疑你想''[A-ZA-Z]',没有'S'。请参阅[最近的答案](https://stackoverflow.com/questions/47445131/how-to-read-string-separated-by-with-scanf/47445307#47445307)。 –

race_info *race = malloc(sizeof(race_info));似乎只针对单个race_info分配空间。

你应该有malloc(lines * sizeof(race_info))适合所有的行。

+0

感谢您的回复。我试过了,但它只是打印了很多零而不是文本。 –

+2

那么可能还有一些其他问题,或许'count_lines()'得到了行数?或者如果某个名称不符合'%[A-Za-z] s'格式? –

+0

我不认为这两者有问题,count_lines()只是返回一个整数,并且所有的名字都符合格式。我和一位朋友谈过,他说它可能与我的内存分配有关,他说我应该尝试使用静态分配。但我不知道我应该怎么做,以及我需要多少内存。 –