Похоже, вам, возможно, придется использовать id
для сопоставления учащихся с результатами, подобными соединению SQL.
Когда вы просматриваете StudentScores.txt и считываете каждый результат во временную Scores
, вам нужно будет найти student
в students
, который соответствует Scores::id
. Найдя этого ученика, вы можете push_back
получить временную оценку.
Что-то вроде
Scores tempscore;
while (inputFile2 >> tempscore) // requires a >> overload for Scores, but here I'm
// just using it as shorthand for "read in a Scores."
// Strongly consider the >> overload though.
{
auto & id = tempscore.id; // make this c++11 proof. C++11 doesn't handle
// capturing members
// find student who matches id
auto found = std::find_if(students.begin(),
students.end(),
[id] (const Student& s) { return s.id == id; })
if (found != students.end()) // actually found a match
{
found->grades.push_back(tempscore); // add score
}
else
{
// handle missing student. Log it and discard? Abort? Your call.
}
}
Документация для std::find_if
[id] (const Student& s) { return s.id == id; }
является лямбда-выражением . Он обеспечивает быструю и грязную функцию, которая вызывается find_if
для проверки, найдена ли она.
Вы можете найти std::map
более полезным для хранения students
, чем std::vector
. std::map<id, Person> students;
делает поиск таким же простым, как
Scores tempscore;
while (inputFile2 >> tempscore)
{
// find student who matches id
try
{
students.at(tempscore.id).grades.push_back(tempscore); // add score
}
catch (const std::out_of_range &)
{
// handle missing student.
}
}
std::map
отлично подходит для простых поисков, но не так хорош в итерации, как std::vector
, и имеет гораздо больше накладных расходов, которые могут превысить экономию при поиске в коротких списках. Если список студентов длинный и программа много ищет в id
s, используйте map
. Если он сканирует весь список, возможно, вам лучше использовать vector
.