Не могу понять этот бесконечный цикл - PullRequest
0 голосов
/ 21 мая 2018

У меня есть этот код, чтобы прочитать файл и затем напечатать каждую строку, но когда я его запускаю, он продолжает печатать '1;0;;0;0;0 'бесконечно.Входной файл содержит это:

1 ; Visitante ; 10 ; 19 ; 2 ; 3
2 ; 1 ; Funcionario ; 8 ; 0 ; 2
3 ; 2 ; Diretor ; 12 ; 19 ; 4
4 ; Visitante ; 8 ; 0 ; 3 ; 2

Код:

#include <stdio.h>
#include <stdlib.h>


void readInput() {
   FILE * fp;
   int id = 0, acompanhantes = 0, entrada = 0, saida = 0, servico = 0;
   char tipo[256] = {};

   if ((fp = fopen("input.txt", "r")) == NULL) {
     printf("Erro a abrir o ficheiro, o programa vai terminar...\n");
     exit(1);
   }

   while ((fscanf(fp,"%d ; %d ; %s ; %d ; %d ; %d\n", &id, &acompanhantes, tipo, &entrada, &saida, &servico)) != EOF) {
     printf("%d ; %d ; %s ; %d ; %d ; %d\n", id, acompanhantes, tipo, entrada, saida, servico);
   }

   fclose(fp);

}

int main() {
  readInput();
}

1 Ответ

0 голосов
/ 21 мая 2018

Вы нажали обычную функцию scanf функций .Если им не удается выполнить сканирование, они просто будут пытаться повторно сканировать один и тот же ввод снова и снова.

В вашем случае первая строка вашего файла не соответствует вашему формату.

1 ; Visitante ; 10 ; 19 ; 2 ; 3
"%d ; %d ; %s ; %d ; %d ; %d\n"

Таким образом, fscanf соответствует первому столбцу и завершается с ошибкой во втором.Он возвращает количество совпадающих элементов: 1. Это не EOF, поэтому он повторяется на одной и той же строке снова и снова.

Обычно это можно исправить, установив fscanf, возвращающее общее количество.элементов для сканирования.fscanf( ... ) >= 6 Но это не решает, что у вас есть файл с разными полями.

Во-первых, мы можем решить множество потенциальных проблем, разделив чтение строки и ее разбор.Используйте fgets + sscanf вместо попыток сделать их одновременно с fscanf.Это не только позволяет избежать бесконечного зацикливания, но и дает нам больше возможностей для синтаксического анализа.

Затем мы можем прочитать строку один раз и попытаться проанализировать ее с различными форматами, пока не сработает один.

char line[4096];
while (fgets( line, sizeof(line), fp) != NULL) {
    if(
        ( sscanf(line,"%d ; %d ; %s ; %d ; %d ; %d\n", &id, &acompanhantes, tipo, &entrada, &saida, &servico) >= 6 ) ||
        ( sscanf(line,"%d ; %s ; %d ; %d ; %d ; %d\n", &id, tipo, &acompanhantes, &entrada, &saida, &servico) >= 6 )
    ) {
        printf("%d ; %d ; %s ; %d ; %d ; %d\n", id, acompanhantes, tipo, entrada, saida, servico);
    }
    else {
        fprintf(stderr, "Could not parse %s.\n", line);
    }
}
...