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

#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. Python赋值魔法技巧

    实验环境: [root@localhost ~]# python -V Python 2.7.5 1.序列解包 多个赋值操作可以同时进行 >>> x,y,z = 1,2,3 > ...

  2. Python socket server demo

    #coding:utf-8 from socket import * #开启ip和端口 ip_port = ("192.168.1.103",8088) print ip_port ...

  3. 转 Hadoop傻瓜化:Datameer大数据收入翻三番

      淘薛奎发布到 <数据极客> 06-28 16:04 随着分析正在成为企业IT的核心,昔日的BI- ETL-EDW分析范型已经完全落伍,不再适用.而力推“大数据傻瓜化”的Datameer ...

  4. 全屏滚动插件之 fullpage.js

    前言:做移动端网页下滑/点击切换到下一页的效果,采用了fullpage,js最新的版本 https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.4 ...

  5. 某国际知名IT公司笔试

    原文地址:http://blog.csdn.net/lazy_tiger/article/details/1790986 这段时间没怎么顾及自己的这个“一寸土地”, 实在惭愧.因为这些天小弟又经历了“ ...

  6. cat echo 打印菜单

    cat << END        =============================        1.apple        2.pear        3.banana   ...

  7. POJ 之 1002 :487-3279

    487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 242418   Accepted: 42978 Descr ...

  8. 英语发音规则---(e)s和-(e)d的读音规则

    英语发音规则---(e)s和-(e)d的读音规则 一.总结 一句话总结: 1.大部分可数名词的复数及动词第三人称单数的一般现在式,是以-(e)s结尾的? moths,glasses:digs,teac ...

  9. 分享知识-快乐自己:关于 String 小案例

    单个字符出现的次数: /*** * 验证是否符合拆分条件 * * @param text * 原字符串 * @param sub * 判断条件 * @return */ public static i ...

  10. Hibernate学习---第十三节:hibernate过滤器和拦截器的实现

    一.hibernate 过滤器 1.在持久化映射文件中配置过滤器,代码如下: <?xml version="1.0"?> <!DOCTYPE hibernate- ...