我看到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
答案 0 :(得分:1)
从结果的外观来看,使用十六进制格式读取成绩:B
,C
和a
是十六进制数字。不过,根据你的意愿,这不应该发生。
在任何情况下,请注意格式化阅读通常会跳过所有前导空格,包括换行符。有几种方法可以处理行结束。通常的做法是将行重新转换为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();
}
}
虽然我认为我原来的代码不能真正重现问题,但我确信上述方法确实可以修复它!