C For循环迭代次数为预期迭代次数的两倍

C For循环迭代次数为预期迭代次数的两倍,c,for-loop,C,For Loop,我正在编写一个C程序,它会提示用户输入文件名,输入时会显示前20行,然后等待用户输入。所以,一切都很好,只是它显示了40行而不是20行,所以我把行数减少到1行,它显示了2行。我甚至尝试了while循环而不是for循环,但结果仍然一样 #include <stdio.h> int main (void) { FILE *in; char file[81], buffer[81]; int flag = 1, c, i; printf("File: "

我正在编写一个C程序,它会提示用户输入文件名,输入时会显示前20行,然后等待用户输入。所以,一切都很好,只是它显示了40行而不是20行,所以我把行数减少到1行,它显示了2行。我甚至尝试了while循环而不是for循环,但结果仍然一样

#include <stdio.h>

int main (void)
{
    FILE *in;
    char file[81], buffer[81];
    int flag = 1, c, i;

    printf("File: ");
    scanf("%s", file);

    if ((in = fopen (file, "r")) == NULL) {
        printf("Unable to open the file: %s\n", file);
        return 1;
    }

    while (flag) {
        for (i = 0; i < 1; i++) {
            if (fgets (buffer, 80, in) != NULL) {
                printf("%s", buffer);
            } else {
                flag = 0;
            }
        }

        c = getchar();
        if (c == (char) 'q')
            flag = 0;
    }

    fclose (in);

    return 0;
}
#包括
内部主(空)
{
文件*in;
字符文件[81],缓冲区[81];
int标志=1,c,i;
printf(“文件:”);
scanf(“%s”,文件);
if((in=fopen(文件,“r”))==NULL){
printf(“无法打开文件:%s\n”,文件);
返回1;
}
while(旗帜){
对于(i=0;i<1;i++){
如果(fgets(缓冲区,80英寸)!=NULL){
printf(“%s”,缓冲区);
}否则{
flag=0;
}
}
c=getchar();
如果(c==(char)'q')
flag=0;
}
fclose(in);
返回0;
}
Stephen G Kochan的C中的问题,第16章,问题6


注意:我不希望有其他方法来解决这个问题,我只是想知道是什么导致了这个问题。

问题是第一个
scanf(“%s”,文件)还有一个剩余的换行符getchar()
第一次拾取的code>语句,因此循环在没有任何用户输入的情况下运行两次

为了防止这种情况,只需在循环之前执行
getchar()

除此之外(如注释所述),
fgets(buffer,80,in)
只需要
buffer[80]


scanf(“%s”,文件)可以像
scanf(“%80s”,文件)那样进行保护
(这里需要保留81个字节,不像在
fgets
)中那样。

我看不到任何计算行数的内容。从1计数到1的
for
循环的目的是什么?它循环是因为
标志
仅在
fgets
失败时设置。为什么会有这个标志?@Barmar更仔细地阅读了这个问题,
1
20
之前;-)@Barmar我刚刚修复了它,它应该只用于一次迭代,这本书有一个错误
char file[81]
并且您可以
fgets(…81…
。如果scanf调用是一个问题,那么为什么它会发生在循环迭代的所有事情上。for循环每次连续运行时,它的迭代次数是第一次的两倍。另外,关于getchar()调用,我不能将其放在循环之前,因为问题需要我先打印20行,然后提示用户输入,如果用户输入“q”,那么程序应该停止,任何其他输入都会导致打印接下来的20行。因为循环中有
getchar
。您输入的字符不是
'q'
,而不仅仅是普通的
enter
?然后在输入缓冲区中会有一个换行符。好的,我得到了它,我尝试对文件名进行硬编码,从而删除了scanf调用,它成功了。显然这不是正确的想法。谢谢