昨日被一个朋友问道一些输入的问题提及到缓存区的时候才明白很多人对缓冲区的概念是很模糊 以至于偶尔会在输入操作上不明所以 何为缓冲区 这个概念最早出现是在我学习c语言的时候 个人理解我们在利用键盘输入数据的时候先进入的是缓冲区 形象一点说缓冲区像是一个屋子 这个屋子有两个门一个只能进 一个只能出 能进的门就是接收我们键盘输入的数据 只能出的门自然就是我们的输入语句了它 但是因为输入语句的限制一些数据我们是无法让其通过这扇门的例如我们在学习c语言的时候scanf语句
#include<bits/stdc++.h>
using namespace std;
int main()
{
char a[100];
scanf("%s",a);
printf("%s",a);
}
这个语句中当我们输入"hello world" 输出只能有 hello 因为scanf不能接收空格回车 而且在遇到这两者的时候就会结束 所以 ' '和回车符只能被留在了缓冲区了 再例如我们c语言中的getchar()语句它是每一次只能接收一个字符
#include<bits/stdc++.h>
using namespace std;
int main()
{
char a[100];
for(int i=0;i<10;i++)a[i]=getchar();
for(int i=0;i<10;i++)printf("%c",a[i]);
}
这段代码中我们输入"a b c d e f g h t q"输出的是"a b c d e " 原因是getchar()只管接收字符不管是什么字符都会接受 我们输入的空格也会被当作字符给接收掉 所以就变成了这样子 那么我们想接收含有空格的字符串那么怎么办呢 我们可以使用其他的输入字符 gets 这个输入语句可以接收含有空格的字符但是任然不能接收回车而且遇到回车就认为输入结束 那么就存在一个问题 请看下面一段代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
char a[100][100];
int j=0;
while(t--)gets(a[j++]);
for(int i=0;i<t;i++)printf("%s\n",a[i]);
}
我们假如输入
2
hello
world
会发现没有输入完成就结束了这是为什么呢 因为gets无法接受回车所以我们在输入完scanf的时候按下回车缓冲区会多出来一个回车 无人接收而我们再输入一个hello的时候缓冲区有两个字符而且存在回车 当gets遇见回车认为结束了就直接跳了出来怎么解决呢 我们用getchar把这个回车提前取出来就好了
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
char a[100][100];
int j=0;
getchar();
while(t--)
{
gets(a[j++]);
}
j--;
while(j>=0)
{
printf("%s\n",a[j--]);
}
}
值得注意的是相同的输入语句不需要去消除回车
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
char a[100][100];
int j=0;
for(int i=0;i<2;i++)
{
gets(a[j++]);
}
j--;
while(j>=0)
{
printf("%s\n",a[j--]);
}
}
当然我们也可以用scanf+正则表达式 scanf("%[^\n],ch]和gets一样还是不能接收回车
下面介绍一下cin.getline的用法
cin.getline(字符数组名,接受长度,结束符)如果输入长度超过我们限制的长度的话会引起cin的错误 在不超过接收长度的时候遇到结束符才算结束
例如cin.getline(ch,200,'\n')接收缓冲区的字符到ch中并且限制长度为200遇见换行结束 例如我们输入hello 然后摁下enter就会结束
cin.getline(ch,200,'\0')的结束标准为'\0'所以这里我们按下enter并不会结束因为'\n'并不是它的结束标准