用fscanf和fgetc读取文本行

时间:2015-11-26 01:22:41

标签: c scanf fgetc

遇到这么小的问题。我试图从文件中读取文本。该文件的格式为:

Jim 3 X Y Z 
James 2 A B
Alley 5 D E F G H 

其中整数表示后面的变量数。 我用fscanf读取名称和数字,然后用fgetc读取char变量,这样我就可以把它们放在一个数组中。 fscanf部分工作正常,但我错过了fgetc的东西。

 do {
    c = fscanf(inputFile, "%s" "%d", word, &inputSize); 
    printf("%s ", word);

    while (c!= '\n')  {
        c = fgetc(inputFile);
        printf("char is:%c ", c);
    }
}while (c != EOF);

这最终导致无限循环。所以我试着告诉fgetc什么时候会停止。

while (c != EOF){
    c = fscanf(inputFile, "%s" "%d", word, &inputSize); 
    printf("%s ", word);
    printf("%d ", inputSize);
    printf("\n");
    for (i =0;i<(inputSize*2);i++) {
            c = fgetc(inputFile) ;
            if (c== ' ') {
            }
            else {
                 printf("char is :%c ", c);
                 printf("\n");
            }
    }

输出变为:

 Jim 3 
 char is :X 
 char is :Y 
 char is :Z 
 James 2 
 char is :A 
 char is :B 
 Alley 5 
 char is :D 
 char is :E 
 char is :F 
 char is :G 
 char is :H 
 Alley 5 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 
 char is :? 

我搞砸了fgetc的哪个部分?另外,为什么fgetc没有看到&#39; \ n&#39;在我的第一个例子中,而是无限循环?

谢谢

1 个答案:

答案 0 :(得分:2)

在原始代码中,您有:

char c;   // Per comments
do {
    c = fscanf(inputFile, "%s" "%d", word, &inputSize); 
    printf("%s ", word);

    while (c!= '\n')  {
        c = fgetc(inputFile);
        printf("char is:%c ", c);
    }
} while (c != EOF);

此代码正常工作,直到您在Alley的数据之后阅读换行符。然后你回到循环的顶部,用fscanf()读取一些数据。由于没有数据,fscanf()会返回EOF,但您可以继续打印wordinputSize之前的内容。然后你进入一个无限循环,因为fgetc()返回的是EOF,而不是\n,所以你再试一次,然后又...... {/ p>

修正:

  1. fgetc()会返回int,而不是char。在普通char是有符号类型的系统上,这意味着您将有效字符(通常为ÿ,U + 00FF,LATIN SMALL LETTER Y WITH DIAERESIS)误认为是EOF。在普通char是无符号类型的系统上,没有任何内容与EOF匹配。这两种行为都不正确。
  2. 测试EOF或换行符;总是想一想。
  3. 测试fscanf()的回报;如果不是2,事情就出错了。
  4. 我会使用顶部检查while循环而不是底部检查do … while循环。有时do … while循环;在我看来,这不是其中之一。

    修订后的代码分析类似。您的代码是:

    char c = 0;
    while (c != EOF){
        c = fscanf(inputFile, "%s" "%d", word, &inputSize); 
        printf("%s ", word);
        printf("%d ", inputSize);
        printf("\n");
        for (i =0;i<(inputSize*2);i++) {
                c = fgetc(inputFile) ;
                if (c== ' ') {
                }
                else {
                     printf("char is :%c ", c);
                     printf("\n");
                }
        }
    }
    

    同样,您需要检查fscanf()返回的值,如果不是2,则退出循环。前三个printf()调用可以合并为一个。 在您第一次阅读Alley的数据后,fscanf()会返回EOF,但您会忽略它并再次打印数据。然后你进入fgetc()循环,它将EOF映射到ÿ(0xFF),但这不是空白,所以你打印它(自己,0xFF不是UTF-8中的有效字节,这可能是打印的问号)。当您完成10次迭代后,c包含一个扩展为EOF的代码,因此循环终止。

    修正:

    • 与以前大致相同。
    • 使用int char;
    • 在继续之前检查fscanf()的回复。
    • fgetc()循环中检查所需的角色或EOF。

    原始代码的可能修复:

    int c;
    while (fscanf(inputFile, "%s%d", word, &inputSize) == 2)
    {
        printf("%s (%d)\n", word, inputSize);
    
        while ((c = getc(inputFile)) != EOF && c != '\n')
        {
            if (c != ' ')
                printf("char is: %c\n", c);
        }
    }