繁体   English   中英

理解 cin.fail() 和 cin.clear - 矢量追加程序

[英]Understanding cin.fail() and cin.clear - Vector Appending Program

这是我在 Stack Overflow 上的第一篇文章,如果我在下面的文章中忽略了任何手续,请原谅我

我目前正在使用 GNU GCC 编译器在 Code::Blocks 17.12 上编写 C++ 程序。 该程序适用于 Big C++ 2nd Edition 的练习 P6.4,我必须编写一个函数来附加/组合用户输入的两个向量,然后返回向量

我可以很好地输入第一个向量,但由于某种原因它不允许我输入第二个向量。

我有一种感觉,在 while 循环中使用 cin.fail() 也会触发我的第二个 bool 值立即更改为 false。 为此,我添加了 cin.clear(),希望它能重置流以允许第二个向量输入,但无济于事。

是真的 cin.fail() 导致了这个错误,还是我忽略了其他东西?

编辑:通过使用 crtl-z,我现在能够获得第二个向量,并运行程序完成,尽管第一个向量 a/a_vct 的最后一个元素复制了两次。 您能否指出一些有关使用 crtl-z 的资源以更好地了解其用途? (还没有在书中介绍它)例如。 如果我为 a_vct 输入 1 2 3,为 b_vct 输入 1 2 3,c_vct 将输出 1 2 3 3 1 2 3 0

#include <iostream>
#include <vector>
using namespace std;

vector<double>append(vector<double>a,vector<double>b)
{
    vector<double>c; //combined vct

    for (int i=0; i<a.size(); i++)
    {
        c.push_back(a[i]);
    }

    for (int i=0; i<b.size(); i++)
    {
        c.push_back(b[i]);
    }

    return c;
};

int main()
{
    vector<double>a_vct; //inputs
    vector<double>b_vct; //inputs
    vector<double>c_vct; //appended vct

    cout<<"Welcome to the vector append-er!"<<endl;

    cout<<"Please enter 1st Vector (enter v to set vector after inputs):"<<endl;
    bool v1_add=true;
    while(v1_add)
    {
        double a;

        cin>>a;
        a_vct.push_back(a);

        if(cin.fail()) //double usage is setting both bools to false???
        {
            v1_add=false;
        }
    }

    cin.clear();

    cout<<"Please enter 2nd Vector. Please enter the same number of elements (enter v to set vector after inputs):"<<endl;
    bool v2_add=true;
    while(v2_add)
    {
        double b;

        cin>>b;
        b_vct.push_back(b);

        if(cin.fail())
        {
            v2_add=false;
        }
    }

    c_vct=append(a_vct,b_vct);

    cout<<"The appended vector is:"<<endl;
    for (int i=0; i<c_vct.size(); i++)
    {
        cout<<c_vct[i]<<" ";
    }


    return 0;
}

编辑 2:根据响应进行新更改,现在按预期工作

if(cin.good())
        {
            a_vct.push_back(a);
        }
if(cin.good())
        {
            b_vct.push_back(b);
        }

在输入第一个向量输入后,为 windows 写Ctrl+Z (通过键盘而不是数字)或Ctrl+D为 linux 使cin.fail()true以停止循环接受输入,并在输入第二个向量输入后.

请注意,向量将重复最后一个条目,因为您在检测到cin.fail()后进行push_back(a) cin.fail() 所以,你可以通过改变来避免这种情况

a_vct.push_back(a);

if(cin.good()) a_vct.push_back(a);

选定的答案解决了当前的问题,但是...

当你有一个失败的输入时,你不仅要清除失败标志,你可能还必须删除错误的输入。 如果您不这样做,则下一次读取将尝试解析相同的错误输入并将再次失败。 删除错误输入通常使用std::istream::ignore 典型用法

cin.ignore(numeric_limits<streamsize>::max(), '\n')

删除流中直到行尾的所有内容。 您可以将'\\n'替换为空格、制表符、逗号或任何其他更符合您要求的字符。 绝对确定您有错误的输入,而不是其他一些失败案例,否则您会发现自己删除了您确实想要的数据。

边注:

 cin>>b;
 b_vct.push_back(b);
 if(cin.fail())
 {
     v2_add=false;
 }

是个坏主意。 如果cin>>b; 失败,您不想将b添加到vector 在添加之前,您要确保b是好的。

 cin>>b;
 if(cin.fail())
 {
     v2_add=false;
 }
 else
 {
     b_vct.push_back(b);
 }

但是我们可以利用cin >>b; 的返回值并稍微重新排列逻辑以使其更容易:

 if(cin>>b) // if read succeeded
 {
     b_vct.push_back(b); // store
 }
 else
 {
     v2_add=false; // read failed
 }

那么,如果我们考虑到while

while(v2_add) // loop until failed
{
    if(cin>>b)
    {
        b_vct.push_back(b);
    }
    else
    {
        v2_add=false;
    }
}

我们看到我们根本不需要if 它正在做一项可以在while条件下完成的工作。

while(cin>>b) // loop until read fails
{
    b_vct.push_back(b); // store
}

由于唯一的出路是失败,这就是你放置clear和可能ignore

while(cin>>b) // loop until read fails
{
    b_vct.push_back(b); // store
}
// Check for EOF here if appropriate
cin.clear(); // clear error flag
// discard invalid input if appropriate
// cin.ignore(numeric_limits<streamsize>::max(), '\n'); // discard up to end of line

如果您有多种可能的字符分隔输入,则通常更容易(但更慢)将违规标记读入std::string并忽略结果。

cin.clear(); // clear error flag
std::string discard;
cin >> discard; // discard whatever follows

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM