首页 文章

用fscanf和fgetc读取文本行

提问于
浏览
0

遇到这样一个小问题 . 我正在尝试从文件中读取文本 . 该文件的格式为:

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在我的第一个例子中没有看到'\ n',而是无限循环?

谢谢

1 回答

  • 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 ,所以你再试一遍,然后......

    修正:

    • fgetc() 返回 int ,而不是 char . 在普通 char 是有符号类型的系统上,这意味着您将有效字符(通常为ÿ,U 00FF,LATIN SMALL LETTER Y WITH DIAERESIS)误认为是EOF . 在普通 char 是无符号类型的系统上,没有任何内容与EOF匹配 . 这两种行为都不正确 .

    • 测试EOF或换行符;总是想一想 .

    • 测试 fscanf() 的回报;如果不是2,事情就出错了 .

    我会使用顶部检查 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中的有效字节,这可能是问题所在's printed). When you'已完成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);
        }
    }
    

相关问题