繁体   English   中英

C 中的 Putchar 和 Getchar

[英]Putchar and Getchar in C

我正在阅读 K&R 的 The C Programming Language 并且对 putchar 和 getchar 感到困惑。 我制作了一个程序,您可以在其中输入 10 个字符,然后程序将它们打印回屏幕。

#include <stdio.h>

int main() 
{
    int i;
    int ch;
    for(i = 0; i < 10; i++)
    {
        printf("Enter a single character >> ");
        ch = getchar();
        putchar(ch);
    }

    return 0;
}

我希望得到这样的 output:

Enter a single character >> a
a
Enter a single character >> b
b

...等等 10 次,但这是我得到的 output:(输入 2 个字符后我停止了)

Enter a single character >> a
aEnter a single character >>
Enter a single character >> b
bEnter a single character >>
Enter a single character >>

不确定为什么我的输入字符与固定字符串组合并成为 output。

另外,我不太确定为什么使用 int 来存储字符。

putchar(ch);

只打印单个字符,随后的printf继续在同一行内。 只需添加:

putchar('\n');

putchar(ch); ,它将在执行printf之前显式地开始新行。 此外,您还应该从输入中获取'\\n' ,该输入在您输入字符后保留在那里:

for(i = 0; i < 10; i++)
{
    printf("Enter a single character >> ");
    ch = getchar();
    getchar();        // <-- "eat" new-line character
    putchar(ch);
    putchar('\n');    // <-- start new line
}

您不是在打印新行。 putchar(ch); 你应该使用putchar('\\n'); 打印一个新行。

用户终端可以在规范和非规范模式下运行。 默认情况下,它在规范模式下运行,这意味着标准输入可用于程序逐行(而不是逐个符号)。 有问题的用户输入了一些东西(让它是字母'a',十六进制的0x61)并按下回车键(十六进制的换行符'0x0A')。 Ascii 表在这里 所以这个动作给了一个程序两个符号。 正如 man getchar() 中提到的那样逐个符号读取它。 所以循环对一个字符迭代两次。 要查看发生了什么,请使用以下程序(+循环计数器输出,+字符代码输出):

#include <stdio.h>
#include <unistd.h>

int main() 
{
  int i;
  char ch;
  for(i = 0; i < 10; i++)
  {
    printf("Enter a single character %d >>", i);
    ch = getchar();
    printf("Ch=0x%08X\n", ch);
    /*putchar(ch);*/
  }

  return 0;
}

输出:

┌─(02:01:16)─(michael@lorry)─(~/tmp/getchar)
└─► gcc -o main main.c; ./main 
Enter a single character 0 >>a
Ch=0x00000061
Enter a single character 1 >>Ch=0x0000000A
Enter a single character 2 >>b
Ch=0x00000062
Enter a single character 3 >>Ch=0x0000000A
Enter a single character 4 >>^C

所以程序得到两个符号并打印它们。 并且新行符号不可见。 所以在问题中用户看到一个奇怪的附加行。 可以在此处找到有关不同终端模式以及如何进行调整的详细说明。

stty实用程序在使用终端选项时也很有用(“icanon”告诉终端是否使用规范模式)。

关于在 getchar() 输出中将字符存储为 int - 请参阅我对类似主题的回答

我们应该关注的术语是“Stream”

“Stream”就像一座桥梁,负责按顺序传输数据。 (程序内外的流畅流式传输的和谐由库/头文件管理,例如 stdio.h)

回到你的问题:

When you type input as 'a' and hit 'enter', you supply 2 values to input stream. - a (ASCII Value : 97) - enter (ASCII Value : 13) /*This 'enter' as an input is the devil. To keep it simple, i will keep calling it as Enter below, and the enter is usually not displayed on screen*/

继续之前的注意/重要/警告:直到您的流没有完全变空,您才能从控制台将新字符写入流中。 (此场景仅暗示使用getchar和putchar,如下图)

这是您的代码:

for(i = 0; i < 10; i++)
    {
        printf("Enter a single character >> ");
        ch = getchar();
        putchar(ch);
    }

循环传递 1: a) You ask user to enter a character. // printf statement b) getchar reads only a single character from stream. c) putchar renders/displays only a single character from stream. d) At first pass you provide input as 'a' but you also hit 'Enter' e) Now, your stream is like a ***QUEUE***, at first pass, and at 1st place of the queue, you have 'a' and at 2nd place 'enter'. a) You ask user to enter a character. // printf statement b) getchar reads only a single character from stream. c) putchar renders/displays only a single character from stream. d) At first pass you provide input as 'a' but you also hit 'Enter' e) Now, your stream is like a ***QUEUE***, at first pass, and at 1st place of the queue, you have 'a' and at 2nd place 'enter'. 队列 f) Once you do putchar, the first character , ie 'a' from the stream/queue gets displayed. e) Loop ends. g) Output of this pass: Enter a single character >>a

循环传递 2: a) You ask user to enter a character. // printf() statement b) Unfortunately your stream isn't empty. It has an "enter" value from the previous pass. c) So, getchar(), reads the next single character, ie 'enter' from stream. (This is where you were expecting to manually enter the next character, but the system did it for you. Read the NOTE/IMPORTANT/CAUTION section mentioned above) d) putchar() displays 'enter' on screen, but since 'enter' is no displayable thing, nothing gets displayed. e) Output of this pass: Enter a single character >> a) You ask user to enter a character. // printf() statement b) Unfortunately your stream isn't empty. It has an "enter" value from the previous pass. c) So, getchar(), reads the next single character, ie 'enter' from stream. (This is where you were expecting to manually enter the next character, but the system did it for you. Read the NOTE/IMPORTANT/CAUTION section mentioned above) d) putchar() displays 'enter' on screen, but since 'enter' is no displayable thing, nothing gets displayed. e) Output of this pass: Enter a single character >>

Loop Pass 3 :与loop 1 类似,这次只输入'b'。

循环传递 4:类似于循环 2

依此类推,直到 10 次通过。 (因此,您可以输入的最后一个字符是“e”。)

推理/结论:

So, long story short, you were expecting to enter the next character, so that getchar would pick your entered value, but since from your previous pass,'enter' value was already waiting in the stream, it got displayed first, giving you such an illusion.

谢谢。 如果您的想法不同,请告诉我。

在偶数次循环, getchar()不是从键盘获取输入,而是从之前输入的命中中获取,因此您还会注意到循环仅执行 5 次。 所以你必须清除缓冲区,即按下输入,以便可以在ch输入新字符。

for (i = 0; i < 5; i++)
    {
        printf("\nEnter a single character >> "); // new line
        ch = getchar();
        while (getchar() != '\n'); //Clearung buffer.
        putchar(ch);
    }

不确定是否理想,但这有效:

    #include <stdio.h>
    int main() 
    {
       int i;
       int ch;
        for(i = 0; i < 10; i++)
        {
            printf("Enter a single character >> ");
            getchar();
            ch=getchar();
            putchar(ch);
         }

         return 0;
       }

我是初学者。 我尝试了这个版本的代码,它给出了所需的输出。

#include <stdio.h>

int main()
{
    int i;
    int ch;
    for(i = 0; i < 10; i++)
    {
        printf("Enter a single character >> ");
        fflush(stdin);
        ch = getchar();
        putchar(ch);
        printf("\n");
    }

    return 0;
}

尽管getchar()获取单个字符,但在用户按 Enter 之前,控制权不会返回给您的程序。 getchar()函数实际上指示 C 接受输入到缓冲区中,缓冲区是为输入保留的内存区域。 直到用户按 Enter 才会释放缓冲区,然后一次释放一个字符的缓冲区内容。 这意味着两件事。 一,用户可以按 Backspace 键来纠正错误的字符输入,只要他或她没有按 Enter。 二,如果您不摆脱它则 Enter 按键会留在输入缓冲区上。要摆脱 Enter 按键,请插入一个额外的getchar()来捕获 Enter 但不对其进行任何操作。所以您只需在 ch = getchar() 之后需要一个额外的getchar ();像这样

#include <stdio.h>
#include <stdlib.h>

int main()
{    int i;
    int ch;
    for(i = 0; i < 10; i++)
    {
        printf("Enter a single character >> ");
        ch = getchar();
        getchar();
        putchar(ch);
    }
    return 0;
}

我设法得到了想要的结果。 我添加了一个换行符和 getchar() 来获取额外的字符。

#include <stdio.h>

int main()
{
int i;
char ch;
for (i = 0; i < 10; i++)
{
    printf("Enter a single character >> ");
    ch = getchar();
    putchar(ch);
    putchar('\n');
    getchar();
    
}

return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM