无法理解这个无限循环

标签 c scanf

我有这个代码来读取文件然后打印每一行但是当我运行它时它一直打印'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();
}

最佳答案

您已点击 a common gotcha of the scanf functions .如果他们扫描失败,他们将不断尝试一遍又一遍地重新扫描相同的输入。

在您的情况下,文件的第一行与您的格式不匹配。

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);
    }
}

关于无法理解这个无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50453658/

相关文章:

c - 在指针中填充 -1 作为特殊值

c - 在c中分割字符串而不改变原始字符串

c - fscanf 具有 double 和字符的文件

c - 使用 fscanf 扫描值或如果不存在值则使用默认值

c++ - fscanf 符合条件

c++ - 使用 sizeof 获得两个的最大幂

c - 格式化代码以访问结构类型的数组索引

python - fseek(fp, 0, SEEK_CUR) 的副作用是什么

更改c语言中的输入文本颜色

c - 在 Windows 控制台上阅读土耳其语字符