getchar()是一个用来获取字符的函数
cpp
#include <stdio.h>
int getchar(void); // 功能:从标准输入(键盘)读取下一个可用的字符
一、讲解
当敲键盘的时候,数据不是直接被getchar()获取,而是先进入了一个"缓冲区(buffer)"
过程:
-
输入
a,b,c...时,getchar()处于一个阻塞状态(没有进行),它在等待一个信号(通常是回车) -
当按下回车键时:
-
回车本身是一个字符(
\n,换行) -
按下回车不仅把
\n放到了缓冲区,还相当于在上面说的信号,告诉getchar(),我的输入已经结束了,可以进行读取了 -
getchar()开始运行:到缓冲区里面,但是只拿走一个字符。getchar()一次只取一个字符。如果你输入了abc然后回车,缓冲区里面其实有4个东西:a,b,c,\n。第一个调用getchar()拿走了a,剩下的b,c,\n还在缓冲区里面排队,下一次调用会直接拿走b,不需要再敲键盘。
-

二、为什么返回值是int,不是char
函数的原型是int getchar(void)。
原因:
-
ASCII码:返回的是字符对应的ASCII,比如
A对应65 -
处理错误(EOF):这是最重要的原因:
-
char类型的范围通常是0-255(unsigned)或-128-127(signed) -
如果读取失败,或读取到文件末尾,
getchar()需要返回一个特殊的标志,叫做EOF(End Of File) -
在标准库中,
EOF通常被定义为-1。 -
有些编译器下的
char是无法表示-1的(比如unsigned char),或者-1恰好代表某个特殊字符 -
为了正确地把"正常字符"和"错误标志EOF"区分开,C语言决定使用范围更大的
int来接受返回值
-
cpp
int c; // 千万不要写 char c;
c = getchar();
if (c != EOF) {
// ...
}
三、注意:scanf后面的getchar会失效
现象:先用scanf读个数字,想再用getchar读个字符,结果程序直接跳过了getchar,不让输入了。
cpp
#include <stdio.h>
int main(){
int num;
char ch;
printf("请输入一个数字:");
scanf("%d", &num);
printf("请输入一个字符:");
ch = getchar(); // 这一行仿佛没执行一样!
printf("你输入了:%d 和 %c\n", num, ch);
return 0;
}

假如输入了2,然后按回车:
-
缓冲区里是
2\n -
scanf读取了2,但是留下了\n在缓冲区。 -
轮到
getchar(),直接读取了缓冲区里的\n。
解决办法
在scanf后面加一个无用的getchar(),专门用来获取遗留的\n
cpp
#include <stdio.h>
int main(){
int num;
char ch;
printf("请输入一个数字:");
scanf("%d", &num);
getchar(); // 专门吃掉缓冲区的 \n
printf("请输入一个字符:");
ch = getchar(); // 这一行仿佛没执行一样!
printf("你输入了:%d 和 %c\n", num, ch);
return 0;
}

常见用法
1. 连续读取直到换行
如果想实现类似gets或fgets(连续读取)的功能:
cpp
#include <stdio.h>
int main(){
int c;
printf("请输入一行文字:\n");
// 只要没读到回车,也没读到文件结束,就一直读
while ((c = getchar()) != '\n' && c != EOF) {
printf("读取了字符: %c (ASCII: %d)\n", c, c);
}
}

2. 清空缓冲区
有时候不知道缓冲区里面剩余多少字符,我想全部清空,为下一次输入做准备
cpp
#include <stdio.h>
int main() {
int password;
int confirm;
// 1. 输入密码
printf("请输入数字密码: ");
scanf("%d", &password);
// ==========================================
// 【关键操作】清空缓冲区
// 循环不断地吃掉字符,直到吃到回车符(\n)为止
// 吃到回车符,说明这一行结束了,循环停止
while (getchar() != '\n');
// ==========================================
// 2. 确认保存
printf("确认保存吗?(Y/N): ");
confirm = getchar(); // 这次它必须等你敲键盘了,因为缓冲区空了
// 3. 打印结果
if (confirm == 'Y' || confirm == 'y') {
printf("保存成功!\n");
} else {
printf("取消保存。\n");
}
return 0;
}
