getchar 和 putchar 是 C 语言标准库里面字符输入输出函数,定义在 stdio.h 头文件,getchar 作用是从标准输入读取一个字符,putchar 作用是向标准输出打印一个字符,两个函数都是单字符操作,和 scanf printf 相比更加轻量,专门处理单个字符,很多初学者容易忽略缓冲区这个关键点,getchar 会读取回车换行符,经常出现程序跳读异常,学习的时候先记住函数原型 返回值,理解行缓冲机制,掌握基本调用写法,再练习循环读取字符,处理换行残留问题,就能熟练使用 getchar 和 putchar 完成字符读写。
基础信息
所属头文件 stdio.h
函数类型 标准库 IO 函数
getchar 函数原型 int getchar (void)
putchar 函数原型 int putchar (int c)
核心特点 一次只处理一个字符,不是字符串
核心功能对照表
| 函数 | 功能 | 返回值 | 参数 |
|---|---|---|---|
| getchar | 从键盘标准输入读取 1 个字符 | 成功返回字符的 ASCII 码,读取结束或者出错返回 EOF | 无参数 |
| putchar | 在控制台输出 1 个字符 | 成功返回输出字符 ASCII 码,出错返回 EOF | 传入字符或者字符 ASCII 码 |
基础调用写法
getchar 读取字符,一般写法
char c;
c = getchar ();
putchar 输出字符,一般写法
putchar (c);
putchar (65); 这里 65 是 ASCII 码,输出大写字母 A
重点原理 输入缓冲区
键盘输入默认是行缓冲模式,用户输入字符之后不会立刻送给 getchar,必须按下回车,这一行数据才会进入缓冲区,getchar 每次从缓冲区取出一个字符,回车对应的换行符也会被当成一个字符,这个就是 getchar 最容易踩坑的地方,连续调用多次 getchar 的时候,上一次残留的换行符会被下一次 getchar 直接读取,不需要用户再次按键。
基础示例代码
include
int main ()
{
char ch;
ch = getchar ();
putchar (ch);
return 0;
}
运行效果 用户输入一个字符按下回车,控制台立刻输出这个字符
循环读取经典用法
while ((ch = getchar ()) != EOF)
{
putchar (ch);
}
这个就是字符回显程序,读取输入的每一个字符,立刻原样输出,Windows 下结束输入是 Ctrl+Z,Linux 系统是 Ctrl+D,EOF 本质是宏,值一般为 - 1。
常见踩坑清单
1 忘记包含 stdio.h 头文件,编译报错
2 把 getchar 返回值定义成 char 类型,处理 EOF 的时候出错,推荐用 int 接收返回值,因为 EOF 是负数,char 有可能是无符号类型
3 连续 getchar,没有清理缓冲区残留换行,程序自动读取换行,不需要按键
4 putchar 参数传入字符串,putchar 只支持单个字符,不能输出字符串,输出字符串要用 puts 或者 printf
getchar putchar 和 scanf printf 对比
getchar putchar 专门单字符,执行效率更高,代码简洁
scanf printf 格式化输入输出,可以处理多种类型,功能更全面,开销更大
如果只需要单个字符读写,优先使用 getchar 和 putchar
【常见问题】
问题 1 getchar 为什么会自动读取回车
回答 1 getchar 读取的是输入缓冲区里面全部字符,按下回车产生换行符,这个换行符也属于缓冲区内容,所以下一次调用 getchar 会直接读到这个回车,这是 getchar 最经典的缓冲区特性。
问题 2 putchar 能不能输出字符串
回答 2 putchar 只能输出单个字符,putchar 不支持字符串,如果需要输出完整字符串,不能只用 putchar,需要循环调用 putchar 逐个输出字符。
问题 3 getchar 返回值为什么推荐用 int 接收
回答 3 getchar 读取失败或者到达文件末尾会返回 EOF,EOF 是负数值,如果用 char 变量接收 getchar 返回值,有可能无法正确识别 EOF,所以规范写法使用 int 变量接收 getchar 返回值。
问题 4 getchar 和 putchar 必须引入 stdio.h 吗
回答 4 getchar 和 putchar 是 stdio.h 里面声明的标准库函数,使用 getchar 和 putchar 必须引入 stdio.h 头文件,不引入头文件部分编译器会报警告或者编译失败。
【免责申明】 本讲解基于标准 C 语言语法,不同编译器对缓冲区和 EOF 实现细节存在差异,代码请结合编译环境测试,不构成嵌入式项目开发唯一规范。


