Как использовать fscanf для переноса огромного количества входных данных из файла в структуру. АНСИ С89(90)

У меня проблема с некоторым кодом в моей программе. Мне нужно прочитать файл и поместить его содержимое построчно в структуру. Файл имеет длину около 800 строк, и когда я пытаюсь распечатать свою структуру, которая теперь должна содержать содержимое файла, она печатает только около 30 строк, как и должно быть. Остальное подается с ошибкой или неправильным форматированием. Это моя функция, как она есть сейчас, и я просто вызываю ее в main. Я не уверен, что не так, но, может быть, это как-то связано с моим вызовом malloc?

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 строк и не переходит от начала файла к концу, а берет содержимое из его середины. Многие строки также имеют неправильное форматирование.

пример работающей программы


person CHr_fred    schedule 25.11.2017    source источник
comment
Приведите пример ввода и вывода, пожалуйста. Что такое count_lines()? Вопросы, требующие помощи в отладке (почему этот код не работает?), должны включать желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения, в самом вопросе. Вопросы без четкой формулировки проблемы бесполезны для других читателей. См. Как создать минимально воспроизводимый пример.   -  person Stargateur    schedule 25.11.2017
comment
Вам нужно проверить возвращаемое значение из fscanf и что-то сделать, если оно не работает. В исходном коде, если какой-либо из этих вызовов завершится ошибкой из-за неожиданно отформатированного ввода, он застрянет там, пытаясь и не сумев прочитать один и тот же неправильный ввод, никогда не добираясь до остальной части файла.   -  person Steve Summit    schedule 25.11.2017
comment
Такие форматы, как %[A-Za-z]s, вероятно, неверны. Я подозреваю, что вы хотите %[A-Za-z] без s. См. этот недавний ответ.   -  person Steve Summit    schedule 25.11.2017


Ответы (1)


Этот race_info *race = malloc(sizeof(race_info));, похоже, выделяет место только для одного race_info.

Вероятно, у вас должно быть malloc(lines * sizeof(race_info)) для всех строк.

person Bo Persson    schedule 25.11.2017
comment
Спасибо за ответ. Я пробовал, но вместо текста печаталось много нулей. - person CHr_fred; 25.11.2017
comment
Тогда может быть какая-то другая проблема, возможно, как count_lines() получить количество строк? Или если какое-то имя не соответствует формату %[A-Za-z]s? - person Bo Persson; 25.11.2017
comment
Я не думаю, что есть проблема с этими двумя, count_lines() просто возвращает целое число, и все имена соответствуют формату. Я разговаривал с другом, и он сказал, что это, вероятно, как-то связано с моим распределением памяти, и он сказал, что я должен попробовать использовать статическое распределение. Но я не уверен, как мне это сделать и сколько памяти мне понадобится. - person CHr_fred; 25.11.2017