这个问题是有一段代码引起的:

代码1:

#include<iostream>
using namespace std;
int main()
{
char t;
t=getchar();
cout<<t<<endl;
ungetc(t,stdin);
cin>>t;
cout<<t<<endl;
}

运行结果:

代码2:

#include<iostream>
using namespace std;
int main()
{
int t;
t=getchar();
cout<<t<<endl;
ungetc(t,stdin);
cin>>t;
cout<<t<<endl;
}

运行结果:

(49是‘1’的ascii码)

代码1的结果是很好理解的,但对于代码二的结果很是纳闷,为什么会这样呢?

查了查ungetc和getchar的资料才明白是怎么回事,当然这是我自己的想法,如果有大神有更加深入的了解,欢迎留言,嘿嘿

我们都知道ungetc的作用是将字符t送回缓冲区,而getchar是从输入的缓冲区中获取一个字符;

getchar的特点:

getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.

一个例子:

#include<iostream>
using namespace std;
int main()
{
char a=getchar();
char b=getchar();
cout<<a<<","<<b<<endl;
}

运行结果:

我们一次输入了“123”,都放到了缓冲区中,但是a值获取了第一个字符‘1’,然后对于b我们不用输入,而是自动从缓冲区获取剩下的字符的第一个,即‘2',如果我们再使用一次getchar呢?没错,获取的正是’3’;

我们回到原来的话题:

对于代码1,t 一开始获取了第一个字符‘1’,然后由ungetc将字符‘1’又送回了缓冲区,然后又使用了cin,因为t是char类型的,所以cin只从缓冲区取出了一个字符‘1’,然后赋给了t.

对于代码2,t 一开始获取了第一个字符‘1’,因为是int类型,所以输出了49,然后由ungetc将字符‘1’又送回了缓冲区,然后又使用了cin,因为t是int类型的,所以cin从缓冲区取出了连续的数字,cin用于输入整数的时候,是通过空格和回车进行分割的,所以这里就取出了123并将其赋给了t.

为了验证我们的猜想,我们还是先使用getchar,用户输入一行数据,然后再使用ungetc将首字符送回,然后在使用cin从缓冲区获取数据并赋值给string类型变量,我们知道string类型变量可以获取连续的字符,并且使用cin获取时是通过空格或者回车进行分割的,所以应该跟代码2的结果类似:

#include<iostream>
using namespace std;
int main()
{
char a=getchar();
ungetc(a,stdin);
string str;
cin>>str;
cout<<a<<","<<str<<endl;
}

运行结果:

此处cin从‘a'开始获取数据直到遇到空格,然后将数据赋给了str

还需要说明的是代码2的程序输入,只适用于整数,当输入的是整数字符(’0‘~’9‘)的时候,cin将缓冲区的数据按照整数的格式赋给了int型变量(注意不是类型转换,我能想到的就是cin的时候自动调用了atoi函数);

当输入的是其他字符的时候,cin就不能把缓冲区中的数据赋给int型变量了。

关于getchar的一些思考的更多相关文章

  1. 关于while((c=getchar()))的一些应用与思考

    最近做题发现一个特别牛逼又特别神奇的读取入字符串的方法 while((c=getchar())!=....) { //do something } 为什么说强大呢,首先这个表达式对空格回车都不怕,他不 ...

  2. 《ODAY安全:软件漏洞分析技术》学习心得-----shellcode的一点小小的思考

    I will Make Impossible To I'm possible -----------LittleHann 看了2个多星期.终于把0DAY这本书给看完了,自己动手将书上的实验一个一个实现 ...

  3. 转:c语言EOF是什么?(及getchar()和putchar用法)

    我学习C语言的时候,遇到的一个问题就是EOF. 它是end of file的缩写,表示"文字流"(stream)的结尾.这里的"文字流",可以是文件(file) ...

  4. 洛谷P1144 最短路计数 及其引申思考

    图论题目练得比较少,发一道spfa的板子题目- 题目:P1144 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: ...

  5. 51nod 1562 玻璃切割 (STL map+一点点的思考)

    1562 玻璃切割 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要 ...

  6. 关于KMP的一点思考

    关于KMP的一点思考 KMP的\(next\)数组的性质很精妙,有必要开一个坑学习一下 Part 1 啥是next \(next[i]\)表示对于\(pre_i\)这个字符串,这个抠出来的字符串本身后 ...

  7. 由endl对printf和cout的思考

    [前言]二者的区别就不介绍了.二者使用方法: printf("%s",a); cout<<a<<endl; endl的作用是什么? 一.endl作用 众所周 ...

  8. 领域驱动和MVVM应用于UWP开发的一些思考

    领域驱动和MVVM应用于UWP开发的一些思考 0x00 起因 有段时间没写博客了,其实最近本来是根据梳理的MSDN上的资料(UWP开发目录整理)有条不紊的进行UWP学习的.学习中有了心得体会或遇到了问 ...

  9. 关于面试题 Array.indexof() 方法的实现及思考

    这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...

随机推荐

  1. socket编程再分析(-)——基础

    linux 网络编程-基础篇 0.Socket简介 socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Inter ...

  2. verilog case 语句合并问题

    有时候在case语句中会有不同选择执行相同操作的情况,为了简化代码,可以将其合并. 以下解答来自百度知道(由于排版问题,有相应修改): reg [1:0]addr_cnt=2'b11; reg rea ...

  3. Spring字符编码过滤器

    1 <filter> 2 <filter-name>characterEncodingFilter</filter-name> 3 <filter-class ...

  4. HihoCoder 1185 : 连通性·三(强连通缩点)

    连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出去,就拜托小Hi ...

  5. yarn  workspace 开发示例

    此为官方示例: package.json { "private": true, "workspaces": [ "workspace-a", ...

  6. Linux环境安装git

    git配置 源码安装 检测当前git版本是否是2.7.4以上 git --version 如果没有安装git直接源码安装即可,如果安装了先删除原来的git. yum -y remove git 先安装 ...

  7. Python学习系列(二)(基础知识)

    Python基础语法 Python学习系列(一)(基础入门) 对于任何一门语言的学习,学语法是最枯燥无味的,但又不得不学,基础概念较繁琐,本文将不多涉及概念解释,用例子进行相关解析,适当与C语言对比, ...

  8. grep 命令使用指南

    grep 命令 grep参数: -E:等同于egrep -o:只匹配你想要的内容,下面是示例: [root@localhost ~]# cat /data/game/config/server_con ...

  9. Oracle用游标删除重复数据

    CREATE OR REPLACE PROCEDURE PR_MOD_BASE IS cursor c_base IS SELECT MIN(INVENTORY_DATE) IDATE,KUNNR,M ...

  10. appium 中swipe()方法向左滑动时

    应该在UI Automator Viewer中读取到的例如ImageView [180,600][900,1320],如果要左滑,代码中应该是写为driver.swipe(900,1320,180,6 ...