1

我一直在阅读 Brian W. Kernighan 和 Dennis M. Ritchie 的 The C Programming Language 并且在字符输入和输出方面,特别是在文件复制方面。书中的例子

#include <stdio.h>

int main(void)
{
    int c;

    c = getchar();

    while (c != EOF)
    {
        putchar(c);

        c = getchar();
    }

return 0;
}

完美运行。

但我决定自己动手改写一下:

#define <stdio.h>

int main(void)
{
    int c;

    printf("Please enter a digit: ");
    c = getchar();

    while (c != EOF)
    {
        printf("The digit entered was: ");
        putchar(c);

        printf("Please enter a digit: ");
        c = getchar();
    }

return 0;
}

编译执行后,我的代码的结果是:

Please enter a digit: 9
The digit entered was: 9Please enter a digit: The digit entered was:
Please enter a digit: *cursor is here*

输入应该是:

Please enter a digit: 9
The digit entered was: 9

Please enter a digit: *the cursor should be here*

另外,我在理解 EOF 时遇到了一点问题。如果有人可以帮助我解决这些问题,那就太好了。

谢谢!

4

4 回答 4

1

大多数“终端”不会“一次一键”将键盘输入发送到程序。相反,终端将等待输入键,然后将所有按下的键(直到该点)发送到目标程序。因此,问题代码会因\n输入换行符和数字而受到影响。

下面的代码丢弃了所有非数字值(但也允许 EOF 值):

#include <stdio.h>
#include <ctype.h>

int main(void)
   {
   int c;

   do {
      c=0;
      /* Get user input */
      printf("Please enter a digit: ");
      while(!isdigit(c) && EOF != c)
         c = getchar();

      /* Produce output. */
      if(c == EOF)
         printf("\n");
      else
         printf("The digit entered was: %c\n", c);
      } while (c != EOF);

   return 0;
   }

编译上述(Linux GCC 示例gcc -Wall -o test *.c:)

然后执行:(Li​​nux示例./test:)

Please enter a digit: 5
The digit entered was: 5
Please enter a digit: 6
The digit entered was: 6
Please enter a digit: <CTRL-D> 

<CTRL-D>通常会生成 EOF 条件。

于 2014-07-15T16:50:45.480 回答
0

因为 ENTER 值“\n”(ASCII 值 10)将通过

getchar(c); 

所以它会第二次

printf("The digit entered was: ");
printf("Please enter a digit: "); 
于 2014-07-15T17:03:16.273 回答
0

You're being tripped up by a trailing newline in your input; when you type 9 and hit Enter, the input stream that your code reads from will contain the encodings for two characters, the 9 and a newline (in ASCII, it would be the sequence of values [57,10]) . Here's how it breaks down:

  1. Code prompts you to enter a digit
  2. You type 9 and hit Enter
  3. Input stream now contains the characters {'9', '\n'};
  4. getchar returns the next available character from the input stream, which is '9'
  5. '9' is not equal to EOF, so you print the digit and prompt for the next character
  6. getchar returns the next available character from the input stream, which is '\n'
  7. '\n' is not equal to EOF, so you print the character and prompt for the next character
  8. The input stream is now empty, so getchar blocks until you type something else.

You can fix this relatively easily:

#include <ctype.h>
...
while (c != EOF)
{
    printf("The digit entered was: ");
    putchar(c);

    printf("Please enter a digit: ");
    do
    {
      c = getchar();
    } while ( isspace( c ));
}

That last little do loop will read characters from the input stream until it sees something that isn't a newline or other whitespace character. You can add an additional check to make sure the character entered really was a digit [0-9]:

while (c != EOF)
{
    printf("The digit entered was: ");
    putchar(c);

    do 
    {
      printf("Please enter a digit: ");
      do
      {
        c = getchar();
      } while ( isspace( c ));

      if ( !isdigit( c ))
        printf( "%c is not a digit!\n" );

    } while ( !isdigit( c ));
}

Now, something to be aware of; what you're storing in c is not the value 9, but the encoding for the character '9', which in ASCII is the integer value 57. If you want to store the value 9 in c, you'll have to do something different.

于 2014-07-15T17:23:36.650 回答
0

嗯,这是您在将您的作品提交到控制台屏幕时提供标准输入的换行符的问题。

让我问你一下:

使用您所说的完美运行的代码,您可能已经尝试了一些输入,比如"Hello!"假设,或者可能只是像"9"您的示例中那样的单个字符。你已经输入了'H'then 'e'then 'l'... 然后'!'然后按enter-key,或者只是'9'然后按enter-key

之后,您的屏幕上有以下内容:

Hello!
Hello!
_

最后一个下划线用于指示闪烁的光标。我的问题是:为什么会在那里?为什么它不是紧挨着最后一个'!'

与 相同的故事9,这将是您屏幕上的内容:

9
9
_

好吧,原因如下:这是因为您的程序又打印了一个您无法直接看到的字符,即换行符'\n'。证明:如果没有打印,下划线会在'!'or旁边闪烁'9'

当您按下enter-key'\n'时,除了您在该会话中输入的任何内容之外,您还使用换行符提供标准输入。标准输入得到所有这些并getchar();一一消耗它们。

在您的代码无法按预期工作时,您使用 提供标准输入'9' '\n'getchar();首先获取'9'and 然后'\n',然后它寻找更多,但没有更多。只有到那时(当没有更多时)它才会向您要求更多。

这就是故事...

为了得到你所期望的,你应该做一些别的事情,我不会直接告诉你,这是一个很好的练习。我可以提示您,您应该while在已有的循环中使用另一个循环,并检查'\n'遇到的条件。

EOF只是一个特殊字符,或者更确切地说是一个值,表示处于文件末尾的特殊情况。对于标准输入,我猜它可以CTRL + D在 Linux 上用组合键发出,它CTRL + Z在 Windows 上。使用该组合然后按回车键应该可以让您摆脱外部循环。

于 2014-07-15T17:04:39.337 回答