这个问题来自于尝试在Accelerated C++中进行练习(第3章中的5,对于任何拥有副本的人),并且已确认仅在运行Lion和Mountain Lion的Mac计算机上进行5.0和llvm g ++ 4.2.1。该程序在带有g ++ 4.8.2的linux上按预期工作。
目标是制定一个程序,可以计算多个学生的成绩,循环输入学生姓名和学生的考试以及多个家庭作业成绩。学生的姓名保存在矢量中,成绩也是如此,这些成绩是根据家庭作业成绩的中位数在现场计算的:
#include <iostream>
#include <ios>
#include <string>
#include <vector>
#include <algorithm>
using std::cout;
using std::cin;
using std::endl;
using std::streamsize;
using std::setprecision;
using std::string;
using std::vector;
typedef vector<double>::size_type vec_sz;
int main()
{
vector<string> students;
vector<double> grades;
string name;
cout << "Enter the student name or EOF to exit and print the grade chart: ";
while (cin >> name) {
students.push_back(name);
cout << "Enter the student's midterm exam grade: ";
int midterm;
cin >> midterm;
cout << "Enter the student's final exem grade: ";
int fexam;
cin >> fexam;
cout << "Enter the student's homework grades followed by an EOF: ";
vector<double> homework;
double grade;
while (cin >> grade) {
homework.push_back(grade);
}
cin.clear();
sort(homework.begin(),homework.end());
vec_sz h_size = homework.size();
if (h_size == 0){
cout << endl << "You must enter the student's grades. Please try again." << endl;
return 1;
}
double median = h_size % 2 == 0
? (homework[h_size/2] + homework[h_size/2 - 1]) / 2
: homework[h_size/2];
grades.push_back(0.2 * midterm + 0.4 * fexam + 0.4 * median);
cout << "Enter the student name or EOF to exit and print the grade chart: ";
}
cout << endl;
if (students.size() != grades.size()) {
cout << "There was an error in the data processing."
<< "The number of students does not equal the number of grades calculated" << endl;
return 1;
}
for (vec_sz size = students.size(), x = 0; x < size; ++x) {
cout << students[x] << ": " << grades[x] << endl;
}
return 0;
}
输入一个学生的信息后,错误就会变得明显。该程序应该返回while (cin >> name)
并接收另一个学生的名字并重复或退出循环EOF。相反,跳过循环,表明cin
循环后while (cin >> grade)
仍处于错误状态。看起来不应该发生这种情况,下一行会有cin.clear()
。
这是一个错误cin
没有重置,是否有解决方案,或者我错过了其他什么?看起来奇怪的是,这种便携式语言的功能会出现如此根本的差异。
提前谢谢!
修改
我在Mac和Linux上运行程序检查cin.eof()
和cin.fail()
的状态,在while (cin >> grade)
的每次迭代以及{{1}之前和之后输出它们}:
cin.clear()
系统似乎同意这些值,这两个位在循环中为while (cin >> grade) {
homework.push_back(grade);
// check status
}
// check status
cin.clear();
// check status
,在0
之后1
并在0
之后重置为cin.clear()
,这似乎表明当函数成功时,输入流确实已关闭,如Dietmar Külh所述。那么问题就是为什么这会发生在Mac系统而不是Linux上。
示例运行是:
Enter the student name or EOF to exit and print the grade chart: Tom
Enter the student's midterm exam grade: 90
Enter the student's final exem grade: 95
Enter the student's homework grades followed by an EOF: 99 67 80
Enter the student name or EOF to exit and print the grade chart:
此时,意外的行为是程序跳过直接输入任何内容的可能性,走出while (cin >> name)
,打印一个等级:
Tom: 88