• C++:关于cin输入ctrl+Z之后不能再用问题的原因


    哈哈哈,我又来了。

    今天写一个需要两次循环输入的程序的时候,出现了一个问题。先贴代码:

    #include<iostream>
    #include<string>
    #include<vector>
    #include<stdexcept>
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::cerr;
    using std::string;
    using std::vector;
    using std::out_of_range;
    
    
    int CalcInt(vector<string> vecStr)
    {
        int i,sum;
        for(i = 0,sum = 0;i!=vecStr.size();++i)
        {
            sum += stoi(vecStr.at(i));
        }
        return sum;
    }
    double CalcDou(vector<string> vecStr)
    {
        int i;
        double sum = 0.0;
        for(i = 0;i != vecStr.size();++i)
        {
            sum += stod(vecStr.at(i));
        }
        return sum;
    }
    int main()
    {
        vector<string> vecStr;
        string str;
        while(cin>>str)
        {
            vecStr.push_back(str);
        }
        try{
            cout<<CalcInt(vecStr)<<endl;
        }
        catch(out_of_range err)
        {
            cout<<err.what()<<endl;
            cout<<"转换整型失败!"<<endl;
        }
        
        vecStr.clear();
        
        while(cin>>str)
        {
            vecStr.push_back(str);
        }
        try{
            cout<<CalcDou(vecStr)<<endl;
        }
        catch(out_of_range err)
        {
            cout<<err.what()<<endl;
            cout<<"转换整型失败!"<<endl;
        }
        
        return 0;
    }

    代码执行如下:

    在我敲完Ctrl+Z并键下回车后,直接出现270和0。然而有代码可知我本来的意思并非如此,本意是想要在输出一次之后,在进行一次输出。

    可是好像第二次的输入直接失败了,还不等我有任何的输入。

    思考了一下,猜想是否是cin的状态位被置为0,导致cin不能输入,强行输入强掳灰飞烟灭,导致输入失败。所以在后面的while输入循环前,加了个cin.clear();对cin标志位进行复位。

    代码如下:

    #include<iostream>
    #include<string>
    #include<vector>
    #include<stdexcept>
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::cerr;
    using std::string;
    using std::vector;
    using std::out_of_range;
    
    
    int CalcInt(vector<string> vecStr)
    {
        int i,sum;
        for(i = 0,sum = 0;i!=vecStr.size();++i)
        {
            sum += stoi(vecStr.at(i));
        }
        return sum;
    }
    double CalcDou(vector<string> vecStr)
    {
        int i;
        double sum = 0.0;
        for(i = 0;i != vecStr.size();++i)
        {
            sum += stod(vecStr.at(i));
        }
        return sum;
    }
    int main()
    {
        vector<string> vecStr;
        string str;
        while(cin>>str)
        {
            vecStr.push_back(str);
        }
        try{
            cout<<CalcInt(vecStr)<<endl;
        }
        catch(out_of_range err)
        {
            cout<<err.what()<<endl;
            cout<<"转换整型失败!"<<endl;
        }
        
        vecStr.clear();
        cin.clear();
        while(cin>>str)
        {
            vecStr.push_back(str);
        }
        try{
            cout<<CalcDou(vecStr)<<endl;
        }
        catch(out_of_range err)
        {
            cout<<err.what()<<endl;
            cout<<"转换整型失败!"<<endl;
        }
        
        return 0;
    }

    其结果如下:

    成功了!

    既然这样了,仔细解释一下原理:

    其实在《C++Primer5E》8.1.2中对IO条件状态有着仔细地解释,但是书上讲的多,而且有些东西讲的比较分散,所以有些东西我总结在这里:

    1.IO操作一个与生俱来的问题就是可能发生错误。一些错误可恢复,而其他错误发生在系统深处,超出应用程序可以修正的范围。故而IO类有定义一些函数和标志,可以帮助我们访问和操纵流的条件状态。具体条件状态可以百度查看。

    2.cin中的条件状态表示主要有四个标志位,badbit,failbit,eofbit,goodbit。其中,badbit在流崩溃的情况下被置位,failbit在IO操作失败的情况下被置位,eofbit在流达到文件结束的时候被置位,goodbit为0表示流未处于错误状态,当goodbit为0时流为有效状态,而另外三个标志位任何一个被置位都将导致流错误。clear()函数将流复位,状态置为有效。

    3.Ctrl+Z表示文件结束符,当cin读到时,则eofbit和failbit都被置位。此时流处于无效状态。

    4.一个流一旦发生错误,其上的后续的IO操作都会失败。

    以上就是原理的概述。

  • 相关阅读:
    HTTP 错误 404.13
    C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录 修改文件名、文件夹名
    设计模式---装饰模式(Decorator)
    设计模式---订阅发布模式(Subscribe/Publish)
    Merge into 详细介绍
    优化案例--多语句表值函数的影响
    常用脚本--Kill所有连接到指定数据库上的回话
    常用脚本--查看当前锁信息
    常用脚本--查看死锁和阻塞usp_who_lock
    常用脚本--在线重建或重整实例下所有索引
  • 原文地址:https://www.cnblogs.com/FWFC/p/8761472.html
Copyright © 2020-2023  润新知