2

我计算输入行数的代码似乎有效。这里是:

#include <stdio.h>

int main()
{
    int counter = 0;

    while(getchar() != EOF)
    {
        if(getchar() == '\n')
        {
            counter += 1;
        }
    }

    printf("Counter: %d", counter);

    return 0;
}

但我的问题是,为什么在 K&R 的书中,当仅在 while 循环条件下测试为真或假时,他们将 getchar 返回值存储在变量中?我认为没有理由这样做。

K&R的版本:

#include <stdio.h> 

main() 
{ 

int c, nl; 
nl = 0; 
while ((c = getchar()) != EOF) 
if (c == '\n') ++nl; 

printf("%d\n", nl); 
}

请注意,“int c”正在存储 getchar 的返回值。

4

6 回答 6

5

例如,如果首先getchar()读取换行符并且条件'\n !=EOF变为真,则进入循环

 while(getchar() != EOF)   

      {
        if(getchar() == '\n') // here reads next character that is not newline
        {
            counter += 1; // missed counting newline , which read by first `getchar()`
        } 
   }  

正如您在上面看到的,一个将无法正常工作。

于 2013-10-15T18:26:59.033 回答
4

您正在做的是您正在读取一个字符并检查它是否等于EOF。然后您正在阅读另一个字符并将其与\n. 这可能会给你一个错误的答案,也可能不会,但这种方法是不正确的,有时会失败。

在书中,他们读取了一个字符并将其存储在变量 c 中并检查它是否为EOF. 然后他们比较c哪个\n是正确的方法。

于 2013-10-15T18:26:12.810 回答
2

K&R 使用变量的原因getchar()是每次迭代不会调用两次,每次调用时getchar(),都会更改输入流的状态。

于 2013-10-15T18:27:15.353 回答
1

为了澄清 Kunal 的答案,您的版本只检查每两个字符中的一个的 EOF/换行符,因为第二个 getchar() 从文件中读取另一个。K&R's 对每个角色都这样做。

于 2013-10-15T18:28:14.123 回答
1

你打getchar()了两次电话,会读到两个不同的字符。在“K&R”代码中,他们将结果存储getchar在一个变量中,以便可以在循环中对其进行分析。它在功能上等同于:

char c = getchar();
while (c  != EOF) 
{  
  if (c == '\n') 
  {
     ++nl; 
  }
  c = getchar();
} 

printf("%d\n", nl);
于 2013-10-15T18:29:15.157 回答
1

getchar()从标准输入返回下一个字符。

当您在 if 语句中调用它时,您将获得下一个字符,但是当您在对 "\n" 的检查中再次调用它时,您将获得该字符之后的字符并进行比较,因此您实际上是在读取两个字符时间,这是错误的。

于 2013-10-15T18:59:04.400 回答