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

代码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. UltraEdit工具安装和注册机破解

    1.关闭网络连接(或者直接拔掉网线). 2.打开UltraEdit软件,稍等片刻会出现提示你你使用的是试用版本的窗口.如下图,点击“注册”. 3.填写许可证id和密码.许可证id可任意填写,不过根据经 ...

  2. C# 浅拷贝与深拷贝(复制)

    在有些时候,我们需要从数据库读取数据填充对象或从硬盘读取文件填充对象,但是这样做相对耗时.这时候我们就想到了对象的拷贝.本文即以实例形式解析了C#浅拷贝和深拷贝的用法. C#中有两种类型变量,一种 是 ...

  3. LeetCode Partition to K Equal Sum Subsets

    原题链接在这里:https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/ 题目: Given an arr ...

  4. FastAdmin 在线命令生成时出错的分析

    FastAdmin 在线命令生成时出错的分析 出错现象 版本环境 FastAdmin 版本:1.0.0.20180806_beta 在线命令插件版本:1.0.3 分析 2018-08-13 16:12 ...

  5. shell中把大写字母转换成小写字母

    shell中把大写字母转换成小写字母 参考:http://www.jb51.net/article/40257.htm echo "AABBCC" | tr "[:upp ...

  6. 【转】使用JMeter 完成常用的压力测试(三)

    使用JMeter 完成常用的压力测试 发布时间: 2008-9-27 15:33    作者: 未知    来源: 网络转载 字体:  小  中  大  | 上一篇 下一篇 | 打印  | 我要投稿 ...

  7. TCP之四:TCP 滑动窗口协议 详解

    滑动窗口机制 滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口:同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口.发送窗口和接收窗口的序号的 ...

  8. Java-Runoob-高级教程:Java 9 新特性

    ylbtech-Java-Runoob-高级教程:Java 9 新特性 1.返回顶部 1. Java 9 新特性 Java 9 发布于 2017 年 9 月 22 日,带来了很多新特性,其中最主要的变 ...

  9. VC散列表

    vc下有2个版本的散列表类,hash_map和unordered_map,hash_map位于stdext命名空间,unordered_map在std命名空间(vs2008及其之后的版本可用),官方推 ...

  10. MFC学习(三)程序入口和执行流程

    1) WIN32 API程序当中,程序入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用程序窗口函数.而在MFC程序当中我们 ...