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