cin在尝试读取失败后读取零

cin reads zero after an unsuccessful attempt to read

本文关键字:读取 失败 cin      更新时间:2023-10-16

我希望用户输入vector<double> a_的值,直到不会读取双值为止。我想做一个二重向量,叫做b_,它的大小取决于a_的大小,实际上它是完全一样的。b_的初始化必须接近a_初始化。但是b_有一些问题,我不明白。b_的所有值都设置为0。

代码:

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<double> a_, b_;
    double tmp;
    while(cin >> tmp) {
        a_.push_back(tmp);
    }
    cout << "A size = " << a_.size() << endl;
    for(int i = 0; i < a_.size(); i++) {
        cin >> tmp;
        b_.push_back(tmp);
    }
    for(int i = 0; i < a_.size(); i ++) { 
        cout << "a[" << i <<"] = " <<a_[i];
        cout << " " <<"b[" << i <<"] = " <<b_[i] << endl;
    }
    return 0;
}

输入为:

4
5
6
e
7
8
9

输出为:

A size = 3
a[0] = 4 b[0] = 0
a[1] = 5 b[1] = 0
a[2] = 6 b[2] = 0

我通过注释添加了一些解释:

while(cin >> tmp) {
    a_.push_back(tmp); // read 4, 5, 6 and push_back them
}                      // the loop ends when extraction fails for reading e

for(int i = 0; i < a_.size(); i++) {
    cin >> tmp;        // extraction fails for reading e everytime, 
                       // and tmp will be set to 0.0
    b_.push_back(tmp); // push_back 0.0 everytime
}

请注意,根据std::basic_stream::operator>>的行为,

如果提取失败,则将0写入值,并设置故障位。如果提取导致值太大或太小而无法容纳值,则写入std::numeric_limits:max()或std::numeric_limits::min(),并设置故障位标志。

设置故障位后,如果要进一步读取,则需要清除故障位并丢弃导致错误的字符。例如:

// ...
cin.clear();
cin.ignore();
for(int i = 0; i < a_.size(); i++) {
    cin >> tmp;
    b_.push_back(tmp);
}
// ...

然后输入:

4
5
6
e
7
8
9

你会得到

A size = 3
a[0] = 4 b[0] = 7
a[1] = 5 b[1] = 8
a[2] = 6 b[2] = 9

实时

一旦格式化提取失败,cin.fail()将返回true。任何进一步的提取也将失败,除非您.clear() failbit

此外,由于错误值仍在输入流中,因此需要.ignore() it:

cout << "A size = " << a_.size() << endl;
std::cin.clear();
std::cin.ignore();
for(int i = 0; i < a_.size(); i++) {
    cin >> tmp;
    b_.push_back(tmp);
}

cin使用"fail"标志来标记内部的输入失败,返回一个空指针,以便"while"可以注意到它。因此,您需要在第一个cin>>tmp之后使用cin.clear()来重置cin的"fail(失败)"标志。

您不应该在"for"循环中使用cin>>tmp,因为您希望一次读取一次数字。

这是一个工作代码:

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<double> a_, b_;
    double tmp;
    while(cin >> tmp) {
        a_.push_back(tmp);
    }
    cin.clear();
    cout << "A size = " << a_.size() << endl;
    for(int i = 0; i < a_.size(); i++) {
        do {tmp = cin.get();} while (tmp=='n');
        b_.push_back(tmp);
    }
    for(int i = 0; i < a_.size(); i ++) { 
        cout << "a[" << i <<"] = " <<a_[i];
        cout << " " <<"b[" << i <<"] = " <<b_[i] << endl;
    }
    return 0;
}

然后输入

4
5
6
a
b
c

你会得到

A size = 3
a[0] = 4 b[0] = 97
a[1] = 5 b[1] = 98
a[2] = 6 b[2] = 99