关于getchar()和putchar()函数的问题

图片描述

图片描述

图片描述

第一张图为什么只输出了一个a呢?而第二张就全输出来了?第三个为什么输出的有是#?(不应该是W吗?)

查了一下好像是和缓冲区有关,但还是不太能理解,而且还说getchar返回的是int类型呢?这又是从哪里体现的呢?

阅读 4.8k
3 个回答

确实跟缓冲区有关, getch每次调用,从标准输入缓冲区中读入1个字符,但如果缓冲区中没有数据,则会阻塞程序,等待直到缓冲区里有数据。

那么什么时候有数据呢?

-- 当你按回车的时候,之前键入的所有字符,包含回车自身,一并被送入输入缓冲区

所以,当缓冲区为空时,无论你输入多少个字符,只要不按回车,getch()函数会一直等在那里。

第一个程序,输入asxsas回车后,getch()获取到第一个字符a,之后的字符还在缓冲区内,当程序退出时,缓冲区销毁,里面的数据也随之消失。

第二个程序可以自己体会下。

第三个程序,翻译一下

每当( (从缓冲区读一个字符) 不等于 '#' )  执行 {  啥也不干,继续循环  }

只有当读到#的时候,才因不满足循环条件而跳出,继续执行下面的putchar,当然 此时打印出的就是 #

getchar返回int类型这个是API里定义的规范,但是你可以将它赋值给一个char类型的变量,这里会自动做int -> char的隐式类型转换,这个转换,会丢失高位字节,但是对于getch()返回的数据来说,他的范围是0-127,高位字节永远都是0,丢了也无所谓

首先这是缓冲区的问题, 缓冲分行缓冲, 全缓冲, 无缓冲三种, 终端默认是行缓冲, 即遇到回车才将缓冲区数据送出.

第一个: 只读一个字符, 回车后输出缓冲区中第一个字符;
第二个: 死循环读字符, 回车后有多少就输出多少;
第三个: 缓冲区一直读, 回车后读到#停止, 所以打印#;

getchar返回是int型, 当读到文件尾时返回EOF(十进制的-1, 十六进制的0xffffffff), 这个值可以确保不会与任何char字符冲突(char取值范围是0x00~0xff)!
阮一峰有篇文章讨论EOF的: EOF是什么?
另, 如果是终端输入, linux下按下ctrl+d表示EOF, Windows下是ctrl+z.

所以你第二个程序最好写成这样:

#include<stdio.h>

int main()
{
    int ch;

    while (EOF != (ch = getchar())) {
        putchar(ch);
    }

    return 0;
}

跨3年来补充第二个程序问题。

刚刚学习K&R的书,也发现这个问题。

其实根本的原因就是getchar从缓冲区读数据,putchar删除n,和while循环的原因。

你输入sdsdjsj,是输入到缓冲区中。

第一次循环,getchar读取了s,其余字符任然在缓冲区中。

然后,你putchar了这个字符s。

第二次循环,缓冲区任然存在数据,所以直接从缓冲区get字符d...然后putchar。

依次推类。。。直到缓冲区干净了,你才有机会用键盘再次向缓冲区输入数据。

其实,输出sdsdjsj,是已经经过了多次循环,多次putchar的结果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进