目录
前置知识:缓冲区
在输入过程中,想要弄懂空格回车换行符,就必须先了解缓冲区的概念
对于缓冲区的解释,推荐下面这篇文章,若已有了解请跳过
各种输入类型
cin
cin属于istream输入流,需要带有头文件#include <iostream>
#include <iostream>
using namespace std;
int main(){
char a, b;
cin >> a;
cin.get(b);
cout << a;
cout << b;
return 0;
}
输入 空格+h+回车
输出 h+回车
由此可知,cin从第一个非空白字符开始读取,遇到空白字符读取结束
换行符留在缓冲区,在本程序中,换行符被cin.get()赋值给了b。
scanf
scanf在输入字符和字符串时,空格回车换行符对其有不同的影响,因此要分开讨论。
输入字符
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
char a;
scanf("%c",&a);
cout << a;
return 0;
}
输入 空格
输出 空格
输入 回车
输出 回车
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
char a, b;
scanf("%c",&a);
cin.get(b);
cout << a;
cout << b;
return 0;
}
输入 a+回车
输出 a+回车
scanf读取字符,可以读取空格或者换行符。
额外的换行符保留在缓冲区,在本程序中,换行符被cin.get(b)赋值给了b。
输入字符串
scanf可以读取C风格的字符串(字符数组),也可以读取C++风格的字符串(string)。
用scanf读取string字符串要预先分配内存空间,直接读取会报错。同时,scanf中对string字符串取址要指向第一个位置str[0]。
一个char数组字符串的地址,默认指向str[0]。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main(){
char b;
char str1[100]; //C风格字符串
string str2; //C++风格字符串
str2.resize(8); //为str2分配内存空间
scanf("%s",&str1);
scanf("%s",&str2[0]);
cin.get(b);
cout << str1;
cout << str2;
cout << b;
return 0;
}
输入 空格+hello+空格+world+回车
输出 hello+world+空格
由此可知,scanf从第一个非空白字符开始读取,遇到空白字符读取结束。
不会读入空白字符
读取结束后,回车留在缓冲区,在本程序中,换行符被cin.get()赋值给b。
cin.get()
用法:
#include <iostream>
using namespace std;
int main(){
char a, b;
//两种表示方法等价
cin.get(a);
b = cin.get();
return 0;
}
cin.get()可读取单个字符,对于空格换行符,与scanf读取字符时用法一致。
从缓冲区读取一个字符,常用于在其他方式输入后,清空缓冲区,防止下次输入出错。
此外,cin.get()不填入任何参数时,常用于windows控制台程序保留窗口,即等待输入一个任意字符。
getchar()
用法:
#include <iostream>
using namespace std;
int main(){
char b;
b = getchar();
return 0;
}
getchar()与cin.get()一样,从缓冲区读取一个字符。
在清空缓冲区与保留windows控制台窗口上也与cin.get()用法相同。
getchar()的使用方法与cin.get()几乎一致,这也是我将这两者放在一起讲的原因。
cin.getline()
只能用于char数组字符串,不能用于string字符串
用法:cin.getline(字符串变量名,字符个数即字符串长度,终止字符);
终止字符:当输入字符串出现终止字符,将停止读取
#include <iostream>
using namespace std;
int main(){
char a[100];
cin.getline(a,10,'b');
cout << a;
return 0;
}
可以清楚看到,终止字符'b'之后的内容都没有被读取。
#include <iostream>
using namespace std;
int main(){
char a[100];
char b;
cin.getline(a,10,'b'); //'b'为终止字符
cin.get(b);
cout << a;
cout << b;
return 0;
}
输入 空格+hel+回车+lo+b+回车
输出 空格+hel+回车+lo+回车
此程序中,空格+hel+回车+lo 都被读取到了字符串a中,由此可见,当存在终止字符时,空格与回车可被cin.getline()读取。
而终止字符后的回车则留存在缓冲区中,被cin.get()读取并赋值给b。
当终止字符省略时,系统默认终止字符为'\0',即换行符,也就是说,按下回车表示输入结束。
#include <iostream>
using namespace std;
int main(){
char a[100];
char b;
cin.getline(a,10);
cin.get(b);
cout << a;
cout << b;
return 0;
}
输入 空格+hello+回车+j+回车
输出 空格+hello+j
我们可以发现,当省略终止符时,cin.getline()依旧可以读取空格。
除此,因为省略了终止符,换行符被默认当成终止符,因此第一个回车并没有进入留在缓冲区。
此时,j被cin.get()赋值给b。
最后输入的换行符仍旧留在缓冲区当中。
getline()
getline()与cin.getline()大同小异。
但是getline()属于string流,而cin.getline()属于istring流
因此,使用getline需要用到头文件#include <string>
而且cin.getline()只能用于C风格的字符串不同,getline()只能用于string类型。
用法:getline(输入流,字符串名,终止字符);
#include <string>
#include <iostream>
using namespace std;
int main(){
string str;
getline(cin,str,'b');
return 0;
}
由于适用于string类型,所以相比于cin.getline(),不需要考虑输入的字符串长度。
getline()的终止字符同样可以省略,具体性质与cin.getline一致。
gets()
用法:gets(字符串变量);
gets只能用于char数组字符串,不能用于string字符串
读取字符串,遇到回车结束。
#include <iostream>
using namespace std;
int main(){
char a[100];
char b;
gets(a);
cin.get(b);
cout << a;
cout << b;
return 0;
}
输入 空格+hello+回车+j+回车
输出 空格+hello+j
gets()可以读取空格,遇到回车结束,但是回车并没有保留在缓冲区。
可以理解为:读取的换行符被转换为'\0'空字符,并以此结束字符串。因此换行符不会留在缓冲区。
注意事项
清空缓冲区
对于cin、scanf、cin.get()、getchar()
以及cin.getline()和getline()使用终止字符时,
使用它们输入字符或字符串,应当注意在输入后使用cin.get()或getchar()清空缓冲区,防止造成下一次输入的错误。
总结
字符OR字符串
用于输入字符:
cin.get() getchar()
用于输入字符串:
cin.getline() getline()gets()
既能输入字符也能输入字符串:
cin scanf
能够读取空格
scanf(仅输入字符)、getline()、cin.getline()、gets()、cin.get()、getchar()
能够读取回车(换行符)
scanf(仅输入字符)、cin.get()、getchar()、cin.getline()(存在终止字符)、getline()(存在终止字符)
不读取回车,但回车不留在缓冲区
cin.getline()(不存在终止字符)、getline()(不存在终止字符)、gets()