今天同学调试一个简单的程序的时候发现了问题,我们两个讨论的时候弄出了好多乐子

#include <iostream>
using namespace std;
int main()
{
    ;
    cout << "c1=";
    while (cin >> c1)
    {
        if ('y' == c1)
        {
            cout << "Good" << endl;
            break;
        }
        else
            cout << "Try again" << endl;
    }

    system("pause");
}

就是这个程序,其实很简单,同学测试的时候每次都是输入的25这样两个字符的数,导致每次打印两个Try again 而发给我测试的时候我都是用2这种一个字符的数

导致程序在我这里是正常的,到他那里就错了。。。。。其实重点是ci是一个字符类型的对象,而且cin是一个流,把键盘输入陆续输出到c1对象,所以25是字符'2'和'5',记录这个主要是告诉自己以后调试的时候要先用别人的测试用例,这样有助于快速定位到问题

----------------------------------------------------------以下为转载内容-------------------------------------------------------------------------------------------------------------

cin在你输入的时候,会跳过空白字符,它们会被放到缓冲区中,当你用接受空白字符的输入流时,这个时候从缓冲区(缓冲区实际上是队列)中获取到它们的

windows按下回车输入的是'\r' '\n'

int main()  

{  

    ]={};  

    ]={};  

    cin >>buf1;
    cin.getline(buf2,); // 这里似乎不等待输入  

    ;  

}  

解决办法如下:

 int main()
{  

    ]={};  

    ]={};  

    cin >>buf1;
    cin.ignore(); // 或者 cin.sync(); 之类的  

    cin.getline(buf2,);  

    ;  

} 

这是为什么呢?

因为,首先, Windows 上敲一下回车键,实质上是输入两个字符:回车符,紧跟着换行符。这两个字符的 ASCII 码分别为 0x0D 和 0x0A,一般来说,其C++转义表示分别为 '\r' 和 '\n'。然后,cin>> 默认是以一个或多个接连的白空格为间隔,cin.getline 默认则以单个换行符(0x0A)为间隔。回车符和换行符都属于白空格。

为了展示这个看不见的回车键敲击,用 istringstream 举个例子:

void disp(char *buf,int n)
{
    ;i<n;++i)
        printf("0x%02X ",buf[i]);
    printf("\n");
}

int main()
{
    disp();
    // 这相当于在控制台敲回车键,然后敲入s1,然后敲回车键,然后敲入s2
    // 0x0D 0x0A 0x73 0x31 0x0D 0x0A 0x73 0x32 0x00
    printf("\n");

    {
        istringstream iss("\r\ns1\r\ns2");
        ]={};
        ]={};

        iss >>buf1;
        iss >>buf2;

        disp(buf1,); // 0x73 0x31 0x00 0x00 0x00
        disp(buf2,); // 0x73 0x32 0x00 0x00 0x00
    }

    printf("\n");

    {
        istringstream iss("\r\ns1\r\ns2");
        ]={};
        ]={};

        iss.getline(buf1,);
        iss.getline(buf2,);

        disp(buf1,); // 0x0D 0x00 0x00 0x00 0x00
        disp(buf2,); // 0x73 0x31 0x0D 0x00 0x00
    }

    ;
}

用 cin 的道理是一样的。区别在于相关的标准库函数会把 0x0D 转换为 0x0A,这就相当于回车键最终敲入缓冲区的是接连的两个换行符。由于这不影响讨论,下文还是用 0x0D 指代。

cin>> 每读到其所期待的东西后碰到 0x0D,就“断”一下,紧跟着的 0x0A 还在缓冲里。此时,如果改用 cin.getline() ,0x0A 立即被读入,而该间隔符前面没有字符,于是就有了 getline 已完成却没有 get 到 line 的错觉。而如果没有改用 cin.getline(),继续用cin>>,那么 cin>> 碰到紧跟着的 0x0A 时,这是在还没读到其所期待的东西就碰到了白空格,它的反应就是跳过该字符(这正是 cin.ignore(); 要做的),接着继续去读其所期待的东西。

关于cin的更多相关文章

  1. cin.ignore()函数的用法

    cin.ignore(a,ch)方法是从输入流(cin)中提取字符,提取的字符被忽略(ignore),不被使用.每抛弃一个字符,它都要计数和比较字符:如果计数值达到a或者被抛弃的字符是ch,则cin. ...

  2. cin的使用问题

    #cin的使用问题 cin输入类型不匹配的情况: #include<iostream> using namespace std; void main() { int i = 0; whil ...

  3. using namespace std 和 using std::cin

    相较using std::cin使用using namespace std不会使得程序的效率变低,或者稳定性降低,只是这样作会将很多的名字引入程序,使得程序员使用的名字集合变小,容易引起命名冲突. 在 ...

  4. while(cin.eof)出错 poj

    zoj遇到c++如何判定输入流结尾的问题,一不小心就超时了 楼下的代码可以通过zoj #include<iostream> using namespace std; int main(){ ...

  5. cin

    cin 是预定义的标准输入流对象,cin 用来接收字符串时,遇“空格”.“TAP”.“回车”时都会结束.

  6. C++输入cout与输出cin

    输入和输出并不是C++语言中的正式组成成分.C和C++本身都没有为输入和输出提供专门的语句结构.输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的.C++的输出和输入是用" ...

  7. cin, cin.getline等函数

    char s[100]; cin>>s;         // 输入一个字符串,遇“空格”.“TAB”.“回车”都结束 cin.getline(s, 20);    // cin.get( ...

  8. strlen 字符型数组和字符数组 sizeof和strlen的区别 cin.get(input,Arsize)

    strlenstrlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值 ...

  9. C++IO关于cin>>和getline的理解

    这个问题困扰了我有一段时间了,趁着十一放假有时间,仔细研究了一下 首先来看一下输入输出运算符cin>>的构成:cin和>> cin>>是由两部分构成的,cin和&g ...

  10. 为什么可以用while(cin)?

    为什么可以用while(cin)?   /** * @brief The quick-and-easy status check. * * This allows you to write const ...

随机推荐

  1. Elasticsearch for python API模块化封装

    Elasticsearch for python API模块化封装 模块的具体功能 检测Elasticsearch节点是否畅通 查询Elasticsearch节点健康状态 查询包含的关键字的日志(展示 ...

  2. 分布式数据库对比评测(Es,mongodb,redis)基础知识篇

    前言 我建议大家看下这个,否则后面你不知道我在说什么. 1.ES数据库相关概念 啥是Es,说白了就是支持文档搜索的分布式数据库,专门方便搜索的,GITHUB京东现在都在用. 1.ES的数据库存放在哪里 ...

  3. Qt事件机制(是动作发生后,一种通知对象的消息,是被动与主动的总和。先处理自己队列中的消息,然后再处理系统消息队列中的消息)

    Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...

  4. Python 3 socket 编程

    Python 3 socket编程 一 客户端/服务器架构 互联网中处处是C/S架构 1.C/S结构,即Client/Server(客户端/服务器)结构 2.在互联网中处处可见c/s架构 比如说浏览器 ...

  5. awk过滤磁盘使用率

    过滤出大于某个值的磁盘使用率: #!/bin/bash diskspace=`df -Ph`IFS="\n" for line in $diskspace;do        ec ...

  6. 如何拯救一台glibc被干掉的Linux服务器

    原文: 如何拯救一台glibc被干掉的Linux服务器? 首先如果 libc.so.6 没有被删除, 直接使用LD_PRELOAD就可以恢复 LD_PRELOAD=/lib64/libc-2.12.s ...

  7. mysql一些操作

    1.产生随机数 SELECT rand();   随机一个0-1的随机数. 2.截取小数点后 SELECT FORMAT(RAND()*10000,2); 在返回 1,306.47 数据中“,” SE ...

  8. Appium-appium日志分析

    查看日志是很重要的一部分,我们在编辑器上测试代码时可以直接进行调试,但持续集成时程序自动运行,如果出现bug,只能通过日志来定位代码位置.appium日志主要分为三部分. 1. 准备阶段,包含了app ...

  9. leetcode 35 Search Insert Position(二分法)

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  10. Convolutional Neural Networks for Visual Recognition 2

    Linear Classification 在上一讲里,我们介绍了图像分类问题以及一个简单的分类模型K-NN模型,我们已经知道K-NN的模型有几个严重的缺陷,第一就是要保存训练集里的所有样本,这个比较 ...