【问题标题】:Why is istream.clear() removing part of my strings while reading doubles and strings?为什么 istream.clear() 在读取双精度和字符串时会删除我的部分字符串?
【发布时间】:2014-12-22 05:00:48
【问题描述】:

我正在阅读一个包含姓名和成绩的文本文件,格式如下:

Polly 95 99 95 94 93 98 99 
Abraham 80 85 81 86 95 78 81 

我使用以下代码将每个学生读入一个 Student_info 结构:

// read homework grades from an input stream into a vector<double>
istream& read_hw(istream& in, vector<double>& hw)
{
    if (in)
    {
        // get rid of previous content
        hw.clear();

        // read hw grades
        double grade;
        while (in >> grade) hw.push_back(grade);

        // clear the stream so that input will work for next student
        in.clear();

    }
    return in;
}

istream& read(istream& in, Student_info& s)
{
    // read and store the student's name, midterm, and final
    in >> s.name >> s.midterm >> s.final;
    //std::cout << "The name is " << s.name << std::endl;

    read_hw(in, s.homework);
    return in;
}

后来我打印了每个学生的姓名和总成绩,但是发生了一些奇怪的事情。而不是得到

Polly 96.6
Abraham 82.2

第一个(Polly)之后的每个名字都被部分切断:

Polly 96.6
raham 82.2

我认为这与清除流以准备下一个学生有关:

in.clear();

好像是把下一个学生名字的开头扔掉了,但是我不能只去掉这行,因为istream需要回到OK状态。

我怎样才能完成这项任务,但要确保我不会丢掉每个学生姓名的一部分? (我假设我事先可能不知道有多少家庭作业,所以我不能简单地阅读 6 个双打然后继续。)

【问题讨论】:

  • 你的阅读循环在哪里?因为到目前为止,您使用我的阅读循环对我有用。

标签: c++ cin istream


【解决方案1】:

我怎样才能完成这项任务,但又要确保我不会丢掉每个学生姓名的一部分?

std::string line;
if (getline(in, line))
{
    std::istringstream iss(line);
    while (iss >> grade)
        hw.push_back(grade);
}

这是一种更结构化的方法,需要在当前行列出数字。

【讨论】:

  • 这是一个明显的解决方法,但它不能解释为什么 OP 代码执行错误。
  • @EMiller:是的。问题是in &gt;&gt; grade 正在尝试转换例如Abrahamdouble,显然在放弃并设置错误流状态之前从流中消耗了几个字符。简单地清除错误状态并不能恢复那些丢失的字符。我不相信这种失败的转换对流的影响有任何保证。很难有:例如gcc 9.2 认为“1E”是一个错误(缺少指数值)而不是一个有效的双精度 1,但到那时它已经消耗了两个字符,并且一些流只让你恢复一个。
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多