C语言字符和字符串输入函数汇总(5个)
上节提到,C语言中有 5 个函数可以从键盘获得用户输入,它们分别是:
scanf() 是最灵活、最复杂、最常用的输入函数,上节我们已经进行了讲解,本节我们接着讲解剩下的函数,也就是字符输入函数和字符串输入函数。
下面的代码演示了 getchar() 的用法:
注意,getche() 位于 conio.h 头文件中,而这个头文件是 Windows 特有的,Linux 和 macOS 下没有包含该头文件。换句话说,getche() 并不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 macOS 下使用。
回显在大部分情况下是有必要的,它能够与用户及时交互,让用户清楚地看到自己输入的内容。但在某些特殊情况下,我们却不希望有回显,例如输入密码,有回显是非常危险的,容易被偷窥。
getch() 使用举例:
注意,和 getche() 一样,getch() 也位于 conio.h 头文件中,也不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 macOS 下使用。
关于缓冲区,我们将在下节《进入缓冲区(缓存)的世界,破解一切与输入输出有关的疑难杂症》中展开讲解。
gets() 的使用也很简单,请看下面的代码:
也就是说,gets() 能读取含有空格的字符串,而 scanf() 不能。
scanf() 是通用的输入函数,它可以读取多种类型的数据。
getchar()、getche() 和 getch() 是专用的字符输入函数,它们在缓冲区和回显方面与 scanf() 有着不同的特性,是 scanf() 不能替代的。
gets() 是专用的字符串输入函数,与 scanf() 相比,gets() 的主要优势是可以读取含有空格的字符串。
scanf() 可以一次性读取多份类型相同或者不同的数据,getchar()、getche()、getch() 和 gets() 每次只能读取一份特定类型的数据,不能一次性读取多份数据。
getche() 和 getch() 都是 Windows 平台特有的扩展函数,但它们的命名不符合规范,所以后来微软又给它们起了新的名字,分别是 _getche() 和 _getch()。
旧名字随时会被丢弃,所以如果编译器产生错误/警告,那么请使用以
根据笔者的测试,旧名字在 VS2022 下虽然可以使用,但是会产生如下的警告(Warning),所以建议大家尽量使用新名字。
函数 | 说明 | 演示 |
---|---|---|
scanf() |
格式化输入函数,可以从键盘读取多种类型的数据。和 printf() 类似,也支持以% 开头的格式说明符。 |
int age = 0; scanf("%d", &age); |
getchar() getche() getch() |
这三个函数都用于输入单个字符,但它们之间是有区别的,后续我们会讲解。 |
char c; c = getchar(); c = getche(); c = getch(); |
gets() | 获取一行数据,并作为字符串处理。 |
char name[30]; gets(name); |
scanf() 是最灵活、最复杂、最常用的输入函数,上节我们已经进行了讲解,本节我们接着讲解剩下的函数,也就是字符输入函数和字符串输入函数。
输入单个字符
输入单个字符当然可以使用 scanf() 这个通用的输入函数,对应的格式控制符为%c
,上节已经讲到了。本节我们重点讲解的是 getchar()、getche() 和 getch() 这三个专用的字符输入函数,它们具有某些 scanf() 没有的特性,是 scanf() 不能代替的。
1) getchar()
最容易理解的字符输入函数是 getchar(),它就是scanf("%c", c)
的替代品,除了更加简洁,没有其它优势了;或者说,getchar() 就是 scanf() 的一个简化版本。下面的代码演示了 getchar() 的用法:
#include <stdio.h> int main() { char c; c = getchar(); printf("c: %c\n", c); return 0; }输入示例:
@↙
c: @
char c = getchar();
2) getche()
getche() 就比较有意思了,它没有缓冲区,输入一个字符后会立即读取,不用等待用户按下回车键,这是它和 scanf()、getchar() 的最大区别。请看下面的代码:#include <stdio.h> #include <conio.h> int main() { char c = getche(); printf("c: %c\n", c); return 0; }输入示例:
@c: @
输入@
后,getche() 立即读取完毕,接着继续执行 printf() 将字符输出,所以没有按下回车键程序就运行结束了。注意,getche() 位于 conio.h 头文件中,而这个头文件是 Windows 特有的,Linux 和 macOS 下没有包含该头文件。换句话说,getche() 并不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 macOS 下使用。
3) getch()
getch() 也没有缓冲区,输入一个字符后会立即读取,不用按下回车键,这一点和 getche() 相同。getch() 的特别之处是它没有回显,看不到输入的字符。所谓回显,就是在控制台上显示出用户输入的字符;没有回显,就不会显示用户输入的字符,就好像根本没有输入一样。回显在大部分情况下是有必要的,它能够与用户及时交互,让用户清楚地看到自己输入的内容。但在某些特殊情况下,我们却不希望有回显,例如输入密码,有回显是非常危险的,容易被偷窥。
getch() 使用举例:
#include <stdio.h> #include <conio.h> int main() { char c = getch(); printf("c: %c\n", c); return 0; }输入
@
后,getch() 会立即读取完毕,接着继续执行 printf() 将字符输出。但是由于 getch() 没有回显,看不到输入的@
字符,所以控制台上最终显示的内容为c: @
。注意,和 getche() 一样,getch() 也位于 conio.h 头文件中,也不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 macOS 下使用。
对三个函数的总结
函数 | 缓冲区 | 头文件 | 回显 | 适用平台 |
---|---|---|---|---|
getchar() | 有 | stdio.h | 有 | Windows、Linux、macOS 等所有平台 |
getche() | 无 | conio.h | 有 | Windows |
getch() | 无 | conio.h | 无 | Windows |
关于缓冲区,我们将在下节《进入缓冲区(缓存)的世界,破解一切与输入输出有关的疑难杂症》中展开讲解。
输入字符串
输入字符串当然可以使用 scanf() 这个通用的输入函数,对应的格式控制符为%s
,上节已经讲到了;本节我们重点讲解的是 gets() 这个专用的字符串输入函数,它拥有一个 scanf() 不具备的特性。gets() 的使用也很简单,请看下面的代码:
#include <stdio.h> int main() { char author[30], lang[30], url[30]; gets(author); printf("author: %s\n", author); gets(lang); printf("lang: %s\n", lang); gets(url); printf("url: %s\n", url); return 0; }运行结果:
YanChangSheng↙
author: YanChangSheng
C-Language↙
lang: C-Language
https://c.biancheng.net https://www.baidu.com↙
url: https://c.biancheng.net https://www.baidu.com
- scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
- gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。
也就是说,gets() 能读取含有空格的字符串,而 scanf() 不能。
总结
C语言中常用的从控制台读取数据的函数有五个,它们分别是 scanf()、getchar()、getche()、getch() 和 gets()。其中 scanf()、getchar()、gets() 是标准函数,适用于所有平台;getche() 和 getch() 不是标准函数,只能用于 Windows。scanf() 是通用的输入函数,它可以读取多种类型的数据。
getchar()、getche() 和 getch() 是专用的字符输入函数,它们在缓冲区和回显方面与 scanf() 有着不同的特性,是 scanf() 不能替代的。
gets() 是专用的字符串输入函数,与 scanf() 相比,gets() 的主要优势是可以读取含有空格的字符串。
scanf() 可以一次性读取多份类型相同或者不同的数据,getchar()、getche()、getch() 和 gets() 每次只能读取一份特定类型的数据,不能一次性读取多份数据。
风险提示
为了和标准库函数进行区分,C/C++ 标准建议:平台特有函数或者扩展函数的命名应该以_
开头。getche() 和 getch() 都是 Windows 平台特有的扩展函数,但它们的命名不符合规范,所以后来微软又给它们起了新的名字,分别是 _getche() 和 _getch()。
旧名字随时会被丢弃,所以如果编译器产生错误/警告,那么请使用以
_
开头的新名字。根据笔者的测试,旧名字在 VS2022 下虽然可以使用,但是会产生如下的警告(Warning),所以建议大家尽量使用新名字。
The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _getche. See online help for details.