C - 用 if 语句重写 for 循环中的 while 循环

C - Rewriting a while-loop in a for-loop with if statements

--小心前面可怕的新手代码--

我正在尝试将这个简单的计数程序从 while 重写为 for

int c, nc;

nc = 0;
while ((c = getchar()) != EOF) {
    if (c != '\n')
        ++nc;
    }
}
printf("%d\n", nc);

这输出 example->8.

到目前为止,我尝试了这几个例子:

int c, nc;
for (nc = 0; ((c = getchar()) != EOF && (c = getchar()) != '\n'); ++nc)
    ;
printf("%d", nc);

int nc;
for (nc = 0; getchar() != EOF; ++nc)
    if (getchar() == '\n')
        --nc;
printf("%d", nc);

这两种尝试都会导致奇怪的输出,如 example->3a->0,而且程序在收到输入后不再 "wait" 中断,它只显示输出并自行关闭。

我想知道这里发生了什么,因为正如我所见,我只是插入(非常笨拙..)一个 if 检查并且似乎无法解释发生了什么..

您正在呼叫 getchar() 两次

for (nc = 0; getchar() != EOF; ++nc)
    if (getchar() == '\n')
        --nc;
printf("%d", nc);

试试这个

int chr;
int nc;

chr = fgetc(stdin);
for (nc = 0 ; chr != EOF ; nc += (chr == '\n') ? 0 : 1)
    chr = fgetc(stdin);
printf("%d\n", nc);

getchar() 等同于 fgetc(stdin) 从输入流 stdin 中读取一个字符,一旦你读取到该字符,你必须处理它,因为它已从流中删除,所以调用该函数两次将从 stdin 中删除两个字符,因此您的计数将是错误的。

因此,如何编写 for 循环并不重要,重要的是每次迭代调用一次 getchar(),例如,这可以工作

int chr;
int nc;

for (nc = 0 ; ((chr = fgetc(stdin)) != EOF) ; nc += (chr == '\n') ? 0 : 1);
printf("%d\n", nc);

或这个

int chr;
int nc;

for (nc = 0 ; ((chr = fgetc(stdin)) != EOF) ; )
{
    if (chr != '\n')
        nc += 1;
}
printf("%d\n", nc);

注意 x = (condition) ? value : another_value 称为 ternary operator,等同于

if (condition)
    x = value;
else
    x = another_value;

可以如下图做

    int nc=0;
    char ch;
    for (; (ch =getchar()) != EOF; )
    {
        if (ch != '\n')
            nc++;
    }

    printf("Count = %d\n",nc);

初始化和递增不是强制性的,它们可以如上所示跳过 code.So 通过这样做,我们实现了与您的 while() 循环相同的效果

这是一种等效的方式,尽管我不太高兴必须将 c 初始化为 \n。 (这样做的原因是get_char是在post步骤中执行的:

int c, nc;

for (c = '\n', nc = 0; c != EOF; c = getchar()) {
    if (c != '\n')
        ++nc;
    }
}
printf("%d\n", nc);

另一种方式是:

int c, nc;
c = getchar();
for (nc = 0; c != EOF; c = getchar()) {
    if (c != '\n')
        ++nc;
    }
}
printf("%d\n", nc);