(十九)cin.get()和system("pause")

简介:

编者注:中间内容可能有误,原理请看文章最后。


当我们需要成程序暂停一会,等待按任意键的时候,可以输入

system("pause");


显示的是 


请按任意键继续。。。


也可以输入:

cin.get();


效果和system("pause")相同,但是不显示任何字符。


而且,有时候需要连续输入2个cin.get();


个人总结出的经验是,当你之前使用过cin>>命令,那么就需要加两个,如果之前没有使用,那么仅需要加一个即可。


至于为什么,按说明是因为cin>>没有读取cin命令中输入的回车字符,而被cin.get()读取了,因此第一个读取了回车,第二个等待读取方能暂停,

 

 

 

cin.get()和cin>>:


原因在于,当我们使用cin的时候,实际上是将输入的字符存在缓存区之中,而cin从缓存区抽取字符。


例如:

先有一个cin>> a; 的命令,于是我们需要输入字符。

我们输入123 456

注意:123和456之间有空格或者TAB命令给的空格。


这个时候,我们输入的123 456被存入缓存区。

输入区-->123 456


进入缓存区:

缓存区-->123 456


然后呢,由于cin>>命令的特点,他会以TAB,空格,回车等作为结束输入,即,他在缓存区中读取到在数字3后面有一个空格或者TAB符(显示出来的都是空格),于是,他认为你输入结束了。


如果之后我们有cout<<a; 那么a显示出来的数字则是123,而不是123 456。


上代码:

#include<iostream>  
using namespace std;
int main() {
int a, b;
cin >> a;
cin >> b;
cout << a << "←这是a" << endl;
cout << b << "←这是b" << endl;
system("pause");
return 0;
}


显示结果为:

123 456
123←这是a
456←这是b
请按任意键继续. . .


 

而cin.get()不同,他不以空格或者回车作为结束,相反,他是将回车当做结束符,但是依然保留,那么就会被下一个读取。

上代码:

#include<iostream>  
using namespace std;
int main() {
int a, b;
a= cin.get();
b= cin.get();
cout << a << "←这是a" << endl;
cout << b << "←这是b" << endl;
system("pause");
return 0;
}


在这个代码中,他输出的结果是:

1
49←这是a
10←这是b
请按任意键继续. . .


 

具体情况是,在我们输入1然后打回车之后,他不需要我们输入第二次,而是直接给我们一个反馈结果,即49和10。为什么不是1呢,因为cin.get()读取的是字符串,(按说明是ASCII值),而1的值是49,回车的值是10。

 

假如我们再换一次,上代码:

#include<iostream>  
using namespace std;
int main() {
int a, b;
a= cin.get();
cin >> b;
cout << a << "←这是a" << endl;
cout << b << "←这是b" << endl;
system("pause");
return 0;
}


输入内容为:1回车,2回车。

显示结果为:

1
2
49←这是a
2←这是b
请按任意键继续. . .


 

我们发现,由于cin>>不读取回车,因此第二个输入的数字被正常的显示出来了,而第一个只显示了ASCII值。

 

再上代码:

#include<iostream>  
using namespace std;
int main()
{
int a, b;
cin >> a;
b= cin.get();
cout << a << "←这是a" << endl;
cout << b << "←这是b" << endl;
system("pause");
return 0;
}


输入为1回车

显示为:

1
1←这是a
10←这是b
请按任意键继续. . .


 

我们发现,由于b读取了缓冲区中的回车字符,因此我们无法输入第二次,而被直接显示出来了。其中a显示正常,为1,b显示为回车的ASCII值。

 

那么假如我们输入的不是数字,是字母,会如何?

上代码:

#include<iostream>  
using namespace std;
int main() {
char a, b;
cin >> a;
b= cin.get();
cout << a << "←这是a" << endl;
cout << b << "←这是b" << endl;
system("pause");
return 0;
}


输入:a回车

显示为:

a
a←这是a
 
←这是b
请按任意键继续. . .


 

我们发现,a被正常显示,而b虽然看起来没有正常显示,但其实已经正常显示,显示的为(回车后换行)。

 

而如果输入的变为a b回车。结果则为:

a
a←这是a
 ←这是b
请按任意键继续. . .


 



原理:

我们输入的内容被储存到缓存区,缓存区也在内存之中

①对于cin来说,对于输入的字符,他实际上是在缓存区读取内存地址,然后根据类型读取字符。原则上,他是从遇见的第一个非空格\TAB\换行字符开始读取,读取类型(比如这里是char)的代码,遇见空字符\空格\TAB\换行字符为止。他不会将未读取的空格\TAB\换行符等舍弃。

 

②对于cin.get()来说,他同样是从缓存区开始读取,根据类型读取相应的内存地址,比如(char类型)就读取一个字符,他会读取空格\换行\tab字符。也不会舍弃。

 

③对于cin.getline()来说,他一直读取到换行符为止,然后丢弃换行符。——注意,这个貌似不能对char类型使用,必须是数组或者字符串才行。

 

比如先cin再cin.get():

①我们输入a和回车。这个时候,cin读取了a,没有舍弃换行符,这个时候,缓存区的换行符被cin.get()读取了,于是之后在b的位置,就显示的是换行。

②如果输入的是空格、a、回车。这个时候,cin没有读取空格,读取的是a,cin.get()读取的是回车,最后显示的和①相同。

③如果输入a、tab(tab键)、回车。这个时候cin读取了a,cinget()读取了tab键,于是a显示a,b显示tab键制造出来的长空格。

 

如果是先cin.get()再cin;

①输入d、e然后回车,cin.get()读取d,cin读取e。于是显示d和e;

②输入空格、d然后回车,cin.get()读取空格,cin读取d,于是显示 空格 和d;

③输入空格、空格、d然后回车,cin.get()读取第一个空格,第二个空格被cin舍弃,然后读取了d,显示空格和d;

④输入d回车、e回车,cin.get()读取d,cin舍弃第一个换行符,读取了e,显示d和e;

⑤输入d回车、回车、e回车。cin.get()读取d,cin舍弃了2个换行符,读取了e。显示的是d和e。

 

如果是2个cin.get():

①输入a回车,输出a和换行;原因参上

②输入空格a,输入空格和a;

 

上文用cin.get()替代system("pause");的原理在于:

①当有cin.get()或者cin>>存在的时候,如果缓存区有内容,将被直接读取,如果没有内容,那么就会要求用户输入相应的内容。

②当之前没有cin>>或者其他需要用户输入内容的代码,cin.get()会发现缓存区没有内容,会要求用户输入内容。于是就起了暂停的功能,但又因为没有赋予其变量,因此不会影响其他。

③当之前假如有一个cin>>,那么用户输入的字符串被cin读取,但是还剩余了一个换行符,这个时候,第一个cin.get()读取的便是这个没有被读取的换行符,第二个cin.get()才起到的是暂停的功能。

④假如用户输入的a(tab键)回车,那么就需要3个cin.get()才行。

⑤有时候在cin.get()读取之后,还要加上一个.get(),比如cin.get(a).get()。第一个cin.get(a)是将用户输入的内容赋值给a,第二个.get()读取了换行符。

 

 


目录
相关文章
|
8月前
|
JavaScript 编译器
模块 &quot;&quot;element-plus&quot;&quot; 没有导出的成员 &quot;ElMessage&quot;。你是想改用 &quot;import ElMessage from &quot;element-plus&quot;&quot; 吗?
模块 &quot;&quot;element-plus&quot;&quot; 没有导出的成员 &quot;ElMessage&quot;。你是想改用 &quot;import ElMessage from &quot;element-plus&quot;&quot; 吗?
225 0
|
自然语言处理
合同结构化文书解析失败,请联系管理员排查:{&quot;code&quot;:3001,&quot;message&quot;:&quot;File transform error&quot;,&quot;success&quot;:false,&quot;tracerId&quot;:&quot;requestId&quot;}报错处理
在使用自然语言处理自学习平台时,标注任务需要上传标注数据,但是使用doc格式上传文件后开始标注时出现了此提示,此篇文章简单介绍下此问题的处理方式。
609 0
合同结构化文书解析失败,请联系管理员排查:{&quot;code&quot;:3001,&quot;message&quot;:&quot;File transform error&quot;,&quot;success&quot;:false,&quot;tracerId&quot;:&quot;requestId&quot;}报错处理
OPA 13 - ok(oButton,&quot;find the Create button&quot;);
Created by Wang, Jerry, last modified on Nov 08, 2015
101 0
OPA 13 - ok(oButton,&quot;find the Create button&quot;);
|
C++
一起谈.NET技术,编写T4模板无法避免的两个话题:&quot;Assembly Locking&quot;&amp;&quot;Debug&quot;
  在这之前,我写了一系列关于代码生成和T4相关的文章,而我现在也试图将T4引入我们自己的开发框架。在实践中遇到了一些问题,也解决了不少问题。如果你也在进行T4相关的开发,相信你也一定会遇到这些问题。为此,特意将这些问题和解决方案与朋友们分享,希望在遇到这些问题的时候少走弯路。
1052 0
|
编译器
arm-none-eabi-g++ -Xlinker -T &quot;../LF3Kmonitor.ld&quot; -Xlinker -Map=&quot;Bogota_ICT_V.map&quot;-ram-hosted.ld -mc
1、arm-none-eabi-g++:是编译ARM裸板用的编译器,不依赖于操作系统。 2、-Xlinker -T "../LF3Kmonitor.ld" -Xlinker -Map="Bogota_ICT_V.map"-ram-hosted.ld -mc      使用连接器:-Xlinker -rpath -Xlinker (-Xlinker -rpath=)        第二个-Xlinker作为参数时表示给连接器传参。
1159 0
|
缓存
Integer.parseInt(&quot;&quot;) Integer.valueOf(&quot;&quot;)和new Integer(&quot;&quot;)之间的区别
把一个String转换成int有Integer.parseInt("")、 Integer.valueOf("")和new Integer("")这么几种方式,它们之间有什么区别呢?我们可以分别看一下它们的源码 //Integer.parseInt("") public static int parseInt(String s) throws NumberFormatExc
1523 0
&quot;catalog&quot; 与 &quot;category&quot; 的区别
catalog 中文翻译为: 目录; category 中文翻译为: 类别; catalog 是有一定顺序的条目(item)列表,或者是分类系统列表。 还可以用作动词,表示编目,将条目放置到某个目录下。
1549 0

热门文章

最新文章