cin丢失每行的前几个字符

时间:2017-07-09 07:06:03

标签: c++ cin cout

我看到other people使用cin.ignore()getline()报告此问题。我理解涉及换行的问题,但我不完全确定如何使用>>进行调试。我正在尝试实施一本成绩单,该成绩单包含学生姓名和考试成绩并输出他们的名字(最终,课程成绩)[来自 Accelerated C ++ ]的第4章。不过,我甚至无法正确输出名称。

// Student.cpp
#include "Student.h"
#include <iostream>
#include <vector>

istream& read(istream& in, Student& s) {
   in >> s.name >> s.midterm;
   read_hw(in, s.homework);
   return in;
}

istream& read_hw(istream& in, vector<double>& hw) {
    if (in) {
       hw.clear();

       double x;
       while (in >> x)
           hw.push_back(x);

       in.clear();
    }
    return in;
}

在这里,我尝试用我的主要功能测试它:

int main() {
    vector<Student> students;
    Student curr_student;

    while (read(cin, curr_student)) {
        cout << curr_student.name;
        students.push_back(curr_student);
        cout << students.size() << endl;
    }

    cout << students.size() << endl;
    for (int i = 0; i < students.size(); i++) {
        cout << students[i].name << endl;
    }
    return 0;
}

但是当我在命令行中输入内容时,第一个学生名字后面的学生姓名输出被截断:

终端输入:

 Alice 50 50 50 50 (<enter>)
 Bob 100 100 100 100 (<enter>)
 Carl 50 50 50 50 (<enter>)
 (<Ctrl-D>)

然后输出:

 Alice
 ob
 rl

1 个答案:

答案 0 :(得分:1)

从结果的外观来看,使用十六进制格式读取成绩:BCa是十六进制数字。不过,根据你的意愿,这不应该发生。

在任何情况下,请注意格式化阅读通常会跳过所有前导空格,包括换行符。有几种方法可以处理行结束。通常的做法是将行重新转换为std::string并使用该字符串初始化std::istringstream

另一种方法是使用行端的自定义定义,通过专门化std::ctype<char>方面来不考虑换行符空格字符。另一种方法是使用一个消耗空格但在遇到换行符时设置std::ios_base::failbit的操纵器。例如:

std::istream& skip(std::istream& in) {
    if (std::istream::sentry kerberos{in, true}) {
        std::istreambuf_iterator<char> it(in), end;
        if (end != (it = std::find_if(it, end, [](unsigned char c){
                return !std::isspace(c) || char(c) == '\n'; }))
            && *it == '\n') {
            ++it;
            in.setstate(std::ios_base::failbit);
         }
    }
    return in;
}
// ...
if (in) {
    while (in >> skip >> x) {
        hw.push_back(x);
    }
    if (!hw.empty()) {
        in.clear();
    }
}

虽然我认为我原来的代码不能真正重现问题,但我确信上述方法确实可以修复它!