【问题标题】:Issues reading multiple types from standard input从标准输入读取多种类型的问题
【发布时间】:2019-10-08 05:15:25
【问题描述】:

我是 C++ 新手,我遇到了从标准输入读取多种类型的问题。我正在尝试接受以下输入:

Smith 93 91 47 90 92 73 100 87
Carpenter 75 90 87 92 93 60 0 98

并为每一行提取不同的字段并将它们存储到一个结构和一个向量中。运行 main.cpp 后,我得到的输出是:

Smith
rpenter

未将完整字符串“Carpenter”完全读入 Student_info.name。它被切断为'renter'。不知道我的问题在这里。谁能帮忙解决这个问题?

#include <iostream>
#include <vector>

using std::istream;
using std::vector;
using std::string;
using std::endl;
using std::cout;
using std::max;
using std::cin;

struct Student_info {
    std::string name;
    double midterm, final;
    std::vector<double> homework;
};

// 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 contents
        hw.clear();

        // read homework grades
        double x;
        while (in >> x) {
            hw.push_back(x);
        }
        // clear the stream so that input will work for the next student
        in.clear();
    }
    return in;
}

istream &read(istream &is, Student_info &s) {
    // read and store the student's name and midterm and final exam grades
    is >> s.name >> s.midterm >> s.final;

    read_hw(is, s.homework); // read and store all the student's homework grades
    return is;
}

int main() {
    vector<Student_info> students;
    Student_info record;
    string::size_type maxlen = 0;

    //read and store all the records, and find the length of the longest name
    while (read(cin, record)) {
        maxlen = max(maxlen, record.name.size());
        students.push_back(record);
    }

    for (vector<Student_info>::size_type i = 0; i != students.size(); ++i) {

        // write the name, padded on the right to maxlen + 1 characters
        cout << students[i].name << endl;

    }

    return 0;
}

【问题讨论】:

  • 用眼睛扫描了一会儿后,我努力解释发生了什么,但我无法解释。因此,我试图重现但我不能:MCVE on coliru。 :-(
  • 我以某种方式怀疑double x; while(in &gt;&gt; x) 消耗Ca 并且无法在失败时将它们推回输入流。 (我手头没有更好的借口。)您是否尝试过使用文件而不是 std::cin 进行测试?
  • 也无法复制。也许它可能是其他声明的一个写得很糟糕的包含。您应该显示完整的源文件,包括声明(#includeusing)。这里唯一的(次要)问题是while (read...),它将尝试读取文件末尾的两倍。
  • @Scheff:即使从控制台读取也能正常工作...
  • 我在std::num_get&lt;&gt;::get() 结束时发现:如果字符匹配“0123456789abcdefxABCDEFX+-”之一。并不是说operator&gt;&gt;(std::istream&amp;, double&amp;) 尝试读取十六进制值。您可以尝试使用不以abcdefABCDEFX 开头的名称来证明这是对还是错……也许,编译器(和操作系统)会有所帮助。 (Compiler Explorer?)

标签: c++ cin


【解决方案1】:

用这个替换 read_hw() 函数中的 while 循环:

while (in.peek() != '\n' && in >> x) {
    hw.push_back(x);
}

但请注意,您必须在单独的行中输入每个学生记录。 此外,在阅读该特定学生记录的最后作业成绩后,用户不应输入除 '\n' 之外的其他字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 2013-03-30
    • 2012-02-17
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2020-10-05
    相关资源
    最近更新 更多