【问题标题】:Counting lines "The C Programming Language" K&R数行“The C Programming Language”K&R
【发布时间】:2013-10-15 18:24:41
【问题描述】:

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

#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的返回值。

【问题讨论】:

  • 如果文件中的第一个字符是换行符会怎样?如果你连续有两个换行符怎么办?您对 getchar() 的第一次调用会咀嚼一个 char,您无法知道究竟咀嚼了什么。
  • @GeorgeMitchell 对,我明白了,谢谢 George。
  • 认为getchar() 的每个调用都读取一个字符,读取一个你许多人继续\n 的行:尝试使用输入文件each $'a\n\n\n\nb' &gt; inputfile

标签: c


【解决方案1】:

例如,如果第一个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()`
        } 
   }  

正如您在上面看到的那样,它无法正常工作。

【讨论】:

  • @Gangadhar 感谢您的澄清,我看到了我的方式的错误:(
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • @D Stanley,谢谢,我已经意识到我的错误,我应该注意到它。 :(
      【解决方案5】:

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

      【讨论】:

      • 谢谢qternion,我应该意识到这一点。愚蠢的错误。
      【解决方案6】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-19
        • 1970-01-01
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        相关资源
        最近更新 更多