首页 > 解决方案 > 通过 C 中的 EOF 停止 While 循环

问题描述

我只是在学习 C,但我的基本理解遇到了问题。我试图做的是打印 X 与输入相同的次数。输入都在同一行,我现在工作得很好。

我遇到的问题是结束程序。我想要做的是在读取该行后让程序结束。

示例:输入 1 2 3

输出:

X
XX
XXX

计划结束

现在我只是永远在循环中......

任何人都可以尝试解释我在这里缺少的概念吗?我确信这可能是语法问题,但我真的想了解我的逻辑在哪里出错。

EOF 在这种情况下如何工作?

    int main(void)

{

int i;

int n = 0;

while ( n  != EOF ) {

scanf( "%d",&n );

    if (n == EOF){

    break;

    }

        for ( i=0; i<n; i++){

        printf("X");
    }

    printf("\n");

}

}

标签: cunixscanf

解决方案


你可以做你想做的事,而不是你正在做的事情......

对于初学者,您必须始终验证scanf. 您必须防范三种情况:

  1. EOF返回 - 表示在遇到任何输入之前已经到达输入的结尾(这可以由用户通过按下Ctrl+d(或Ctrl+z在 windows 1上)手动生成);

  2. 返回的转换说明符数少于此数,表示匹配输入失败(发生这种情况时,从流中提取字符会停止,有责任在下次尝试读取之前删除任何无关字符);或者

  3. 返回等于转换说明符的数量——表示数据已转换并存储在您提供的每个变量中;

此外,您必须验证收到的输入是否在可接受的范围内。(您可能不希望输入负值

对于您的代码,您可以简单地验证上面的 (3) 并退出 on EOF,或者匹配输入失败——因为您只读取 1 类数据 ( integers) 并且可以在任何失败时退出。

但这并不能解决你的问题。解决此问题的正确方法是一次读取一行数据(使用fgets或 POSIX getline),然后通过重复调用解析数据行中的每个整数值,strtol并利用其endptr参数沿着整行工作. (关于它的正确使用有很多关于 SO 的例子)

但是,您也可以通过在读取每个字符后简单地检查下一个字符来做您想做的事情intgetchar()如果是'\n',那么您的读取已完成,否则您需要将字符放回使用并验证放回成功通过什么方式?(提示:检查返回——每个 C 库函数的返回都清楚地描述在它的关联中——使用它们stdinungetcman page:)

总而言之,您可以执行以下操作:

#include <stdio.h>

int main (void) {

    int i, n;

    printf ("input: ");

    while (scanf ("%d", &n) == 1) { /* validate the 'return' of scanf */
        if (n < 0) {    /* validate n not negative */
            fprintf (stderr, "error, input cannot be negative.\n");
            return 1;
        }
        for (i = 0; i < n; i++)     /* then loop that number of times   */
            putchar ('X');          /* don't printf 1-char, use putchar */
        putchar ('\n');             /* tidy up with newline */

        i = getchar();      /* read next char in stdin */
        if (i == '\n')      /* if end of line - break (done) */
            break;
        else if (ungetc (i, stdin) != i) {  /* validate putting it back */
            fprintf (stderr, "error: putting char back in stdin.\n");
            return 1;
        }
    }

    return 0;
}

示例使用/输出

$ ./bin/output_x
input: 1 2 3
X
XX
XXX

或者

$ ./bin/output_x
input: 7 1 1 5 1 1 1
XXXXXXX
X
X
XXXXX
X
X
X

如果您还有其他问题,请仔细查看并告诉我。

脚注

  1. 但请参阅:CTRL+Z 在 Windows 10 中不会生成 EOF

推荐阅读