我正在编写一个简单的c ++程序,该程序从输入中读取学生的姓氏,然后是期中,期末和各种作业成绩(例如:Carlo 2 5 7 8)。 问题在于,从输入的第二行开始,它削减了一些学生的姓氏。
一个例子。
Enter the surname of each student followed by the midterm, final, and homework grades.
Carlo 2 3 4 5
Bonandrini 2 3 4 5
Carlo 3.4
onandrini 3.4
如您所见,第二个名字在前面缺少a。 我尝试了不同的名称和名称的长度,但是没有任何变化,它仍然可以剪切名称。 据我了解,问题出在输入本身。
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<ios>
#include<iomanip>
#include<stdexcept>
template<typename T>
T median(std::vector<T> vec) // Not passed by name because we sort the vector
{
typedef typename std::vector<T>::size_type vec_sz;
vec_sz size = vec.size();
if(!size)
throw std::domain_error("Median of an empty vector");
std::sort(vec.begin(), vec.end());
vec_sz pos = size / 2;
return size % 2 == 0 ? (vec[pos] + vec[pos-1]) / 2 : vec[pos];
}
template<typename T>
std::istream& operator>>(std::istream& stream, std::vector<T>& vec)
{
if(stream) // If stream is actually open
{
vec.clear(); // In case the vector wasn't empty
T x;
while(stream >> x)
vec.push_back(x);
stream.clear();
}
return stream;
}
struct StudentInfo
{
std::string name;
double midterm, final;
std::vector<double> homework;
};
double grade(const StudentInfo& student)
{
return 0.2 * student.midterm + 0.4 * student.final + 0.4 * median<double>(student.homework);
}
std::istream& operator>>(std::istream& stream, StudentInfo& student)
{
stream >> student.name >> student.midterm >> student.final;
stream >> student.homework;
return stream;
}
int main()
{
std::cout << "Enter the surname of each student followed by the midterm, final, and homework grades" << std::endl;
std::vector<StudentInfo> students;
std::string::size_type maxlen = 0;
StudentInfo student;
while(std::cin >> student)
{
maxlen = std::max(maxlen, student.name.size());
students.push_back(student);
}
std::sort(students.begin(), students.end(),
[](const StudentInfo& student1, const StudentInfo& student2){ return student1.name < student2.name; });
for(StudentInfo student : students)
{
// + 1 to put a space between the name and the grade
std::cout << student.name << std::string(maxlen + 1 - student.name.size(), ' ');
try{
double points = grade(student);
std::streamsize prec = std::cout.precision();
std::cout << std::setprecision(3) << points << std::setprecision(prec);
}
catch(std::domain_error e){
std::cout << e.what();
}
std::cout << std::endl;
}
}
程序应输出具有适当年级的学生列表。
答案 0 :(得分:0)
我将假设名称是“ First Last”或“ Last,First”之类的意思。
如果是这种情况,则问题出在您使用std :: stream >> std :: string上。此输入限定空格。除非您告诉它,否则空格后的所有内容均视为新字符串。如果期中字符串不是双精度数,则空格后面的部分将显示在此处。相反,它只是忽略它,因为它不知道如何将其转换为字符串。
您需要的是std :: stream.getline()可能会解决问题。