1. 几种从键盘获得输入的函数
- 单个字符输入函数 getchar()
int getchar(void)
/没有参数
/返回输入的字符相应的ascii码值,可根据返回值判断输入是否结束
/工作原理:从输入缓冲区中读取一个字符
/有缓冲区
/有回显
/不自带输入结束标志,需自定义
/头文件stdio.h
扩展:
getche()
int getche(void)
/工作原理:从键盘接收一个字符
/无缓冲区
/有回显
/头文件conio.h
getch()
int getch(void):
/工作原理:从键盘接收一个字符
/无缓冲区
/不带回显(可用于输密码、实现“按任意键继续”的效果)
/头文件conio.h
注意:getche() 并不是标准函数,位于 conio.h 头文件中,默认只能在 Windows 下使用,不能在 Linux 和 Mac OS 下使用。
- 行输入函数 gets()、fgets()
char * gets(char * str)
/非格式化输入函数
/返回值为输入的字符串
/行缓冲
/带回显
/工作原理:从输入缓冲区读取输入知道遇到回车符
/输入结束标志:将回车看作数据输入结束的标志,同时会将回车符从输入流中读出(*),但不作为字符串的一部分;可用于带空格的字符串输入
/头文件stdio.h
/注意:不能够检测到数组的结束地址,当数组长度固定,而实际输入的字符数大于数组长度时,会产生数据泄露问题
fgets(数组首地址,size,stdin)
/参数见原型
/返回值为输入的字符串
/工作原理:从输入流中读出数组大小的数据,防止了数据泄露
- 格式化输入函数 scanf()
scanf()函数既可以进行单个字符的输入,也可以进行行输入。
int scanf("格式控制字符串",变量地址)
/有参数,参数如原型所示
/返回成功赋值的数据项数,读到文件末尾或出错时返回EOF,可根据返回值判断输入的合法性以及输入是否结束
/行缓冲
/带回显
/工作原理:从输入缓冲区中按照scanf函数第一个参数规定的格式进行读取符合格式的数据,放到对应的变量中,直到遇到空白字符
/输入结束标志:将空格、回车、制表符等空白字符当作数据输入的结束标志。空白字符不会被从输入流读取,在下一次输入时就会被读取到你的字符变量中影响下一次输入。解决:在输入一个字符前,调用一次getchar()函数;或scanf(" %c",&ch)
/头文件 stdio.h
/注意:不能够检测到数组的结束地址,当数组长度固定,而实际输入的字符数大于数组长度时,会产生数据泄露问题
2. 输入包含空格、制表符、换行符的字符串
在上面对各种从键盘获得输入的函数有了了解之后,就需要根据具体需求选择合适的输入函数。
-
一般来说,单个字符输入就选择getchar()函数;
-
要输入一行包含空格符的字符串就选择gets()和fgets()函数;
-
不包含空白符的字符串输入就选择scanf()函数。
但是,有时候需要我们输入包含空格、制表符、换行符的不定个数字符的字符串,该怎么选择?
如PTA浙大版《C语言程序设计(第3版)》题目集中的一道题目:
在该题目中,虽然并不是考察点,但或许有人感兴趣,要如何实现void ReadString( char s[] );函数呢?
此时在选择输入函数时就要考虑未知输入数量时如何判断输入是否结束,以及未知数量的输入如何存储的问题。未知数量的输入如何判断输入是否结束的问题可以参考我的上篇博客XX。
未知数量的输入可以选择定义相应数据类型的vector对象来进行存储,vector相关知识点可以参考我的博客XXX。
在解决这个问题时,我选择采用循环调用getchar()函数的方式来进行输入。要注意的是,getchar()没有输入结束标志,此时就需要在调用时以while((ch=getchar())!=EOF)来判断输入是否结束。
示例:
#include<iostream>
#include<vector>
#include<stdio.h>
using namespace std;
int main()
{
vector <char> str;
//solution 1
int i=0;
//输入
printf("使用getchar()输入包含空格、制表符、回车的字符串:\n");
char ch;
while((ch=getchar())!=EOF)
{
str.push_back(ch);
}
//输出
printf("使用putchar()输出包含空格、制表符、回车的字符串:\n");
i=0;
while(str[i])
{
putchar(str[i]);
i++;
}
运行结果如下图所示:
**注意:**该示例在windows中进行,EOF的键盘输入为:
1)若在行首结束输入,则键入Ctrl-z,再键入enter;
2)若再非行首的位置结束输入,则键入enter,再键入Ctrl-z,再键入enter。
不同系统、不同情况下该如何从键盘输入EOF,同样请参考我的上一篇博客XX。
3. 输入不定个数的数字
同样的,问题来源于PTA浙大版《C语言程序设计(第3版)》题目集中的一道题目:
其实题目给定了输入结束标志,但是我想考虑的问题是未知个数、没有输入结束标志的数字输入。要如何输入呢?
类似于字符串的输入,考虑用vector对象存储不断输入的数字。
输入函数选择scanf,用其返回值来判断是否结束输入。
示例:
#include<iostream>
#include<vector>
#include<stdio.h>
using namespace std;
int main()
{
vector<int> num;
printf("使用scanf输入不定个数的数字:\n");
int a;
while(scanf("%d ",&a)!=EOF)//注意是"%d "而不能是"%d",可读性差是一个原因,更重要的是不加空格会认为你输入的是一个数
{
num.push_back(a);
}
printf("一共输入了%d个数字\n",num.size());
for(int i=0;i<num.size();i++)
{
cout<<num[i]<<endl;
}
}
输入及运行结果如下图:
要注意的是,该情况下从键盘键入EOF的操作是:
键入enter,再键入Ctrl-z,此时输入回显为^Z,此时键入enter并不会结束输入,而是将光标移到下一行,要再次键入键入Ctrl-z,再键入enter,才会结束输入。
所以在结束输入前,回显有两行的^Z