首页 > 解决方案 > 为什么 cout() 会砍掉多个字符?

问题描述

#include <iostream>
#include <vector>

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

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

istream& read_hw(istream& in, vector<double>& hw)
{
    if (in) {
        hw.clear();
        double x;
        while (in >> x) {
            cout << "double Grade from read_hw(): " <<  x << "\n";
            hw.push_back(x);
        }
        in.clear();
        }
    return in;
}

istream& read(istream& is, Student_info& s)
{
    is >> s.name >> s.midterm >> s.final;
    std::cout << "string Name from read()" << s.name << std::endl;
    read_hw(is, s.homework);  // read and store all the student's homework grades
    return is;
}

int main() {
  Student_info s;
  vector<double> hw;
  while (read(cin, s)) {
    cout << "String name from main()" << s.name << endl;
  }
}

输入/输出示例:(我输入了 Jimbo 99 99 99 99,它按预期打印。然后我输入了 Failure 5 5 5 5 5,结果如下所示。)

String name from main()Jimbo
string Name from read()lure
double Grade from read_hw(): 5
double Grade from read_hw(): 5
double Grade from read_hw(): 5
Failure 10 10 10 10 10 // new input.
String name from main()lure
string Name from read()lure
double Grade from read_hw(): 10
double Grade from read_hw(): 10
double Grade from read_hw(): 10
Jimbo 99 99 99 99 99 // new input again. note it prints Jimbo just fine.
String name from main()lure
string Name from read()Jimbo
double Grade from read_hw(): 99
double Grade from read_hw(): 99
double Grade from read_hw(): 99

我已经尝试过搜索,但我得到的只是关于 ignore() 的东西,我没有使用它。我有一种预感,这与使用while (cin >> x)which 进行双打有关,然后立即切换到在下一个read()循环中接收字符串。

标签: c++

解决方案


你得到这个结果是因为在看到一封信后不会立即cin >> x失败数字和类似数字的实体中允许使用某些字母。顺便说一句,F、A 和 I(任何一种情况)都在其中(它们出现在 指定特殊浮点 IEEE 值的字符串中)infnan所以cin >> x 会消耗“Fai”然后才会失败。

另一方面,J 不是这样的字母,因此在看到 Jcin >> x时会立即失败,将字母留在流中以供下次读取。

缓解策略包括

  • 阅读并每行解析一个学生记录
  • 读取标记并识别它们是否是数字(但谁说一个人的名字不能是数字?)
  • 在学生记录之间引入明确的分隔符,例如“|”。

推荐阅读