Background: students' test scores are saved in separate files, one for each subject. Each student takes every subject, so each name needs to be recorded just once across the files
Objective: to read the scores of each (unique) student across the various subject files and store them in struct StudentScores objects
My approach: use a std::vector<pair<std::string, std::vector<double>>> to hold the interim results where the string is the student's name and the vector<double> his/her scores (yes, it could even be a std::vector<std::map<std::string, double>> to save the subject information along with the scores but let me try and get this one going first). Steps are: open file → getline() → stringstream the line → read off name and the scores → now use std::find_if() on the above vector<pair<string, vector<double>>> → if name found, (*itr).second.push_back(score), else make_pair(name, score) and push_back this pair into the above vector. Finally, the idea was to create StudentScores objects with the information from this vector<pair<...>>
Problem and some preliminary diagnosis: completely blank output, nothing, nada … I broke the entire program down into smaller chunks and the multiple file reading seems OK but it appears std::find_if() is not working while the files are being read. That said, its my best guess at the moment and I could be wrong
Code:
Code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <tuple>
struct StudentScores
{
std::string m_name = "";
double m_quizAvg = 0.0;
double m_sportsAvg = 0.0;
StudentScores (const std::string name, const std::vector<double>& scores) : m_name(name)
{
m_quizAvg = scores[0]; m_sportsAvg = scores[1];
}
};
std::ostream& operator << (std::ostream& os, const StudentScores& s)
{
os << "Student " << s.m_name << "\n";
os << "Quiz: " << s.m_quizAvg << " Sports " << s.m_sportsAvg << "\n";
return os;
}
int main()
{
std::vector<std::string> fileNames{"D:\\quiz.txt", "D:\\sports.txt"};
std::vector<std::pair<std::string, std::vector<double>>> interimResults{};
for (const auto& elem : fileNames)
{
std::ifstream inFile{elem};
if(inFile)
{
std::string line{};
while (getline(inFile, line))
{
std::istringstream stream{line};
std::string tempName{};
double tempOne{}, tempTwo{}, tempThree{};
stream >> tempName >> tempOne >> tempTwo >> tempThree;
auto tempAvg = (tempOne + tempTwo + tempThree) / 3;
if(inFile)
{
for (auto & elem : interimResults)
{
auto itr = std::find_if(interimResults.begin(), interimResults.end(),
[&tempName](std::pair<std::string, std::vector<double>>& element)
{return element.first == tempName;});
if (itr != interimResults.end())
{
(*itr).second.push_back(tempAvg);
}
else
{
std::vector<double> tempScores{tempAvg};
auto tempPair = std::make_pair(tempName, tempScores);
interimResults.push_back(std::move(tempPair));
}
}
}
}
}
}
std::vector<StudentScores> allScores{};
for (const auto& elem : interimResults)
{
StudentScores temp(elem.first, elem.second);
allScores.push_back(std::move(temp));
}
for (const auto& elem : allScores)std::cout << elem ;
}
Text files:
//Quiz:
Aron 1.2 34.5 6.7
Ben 8.9 9.8 7.6
Cindy 5.4 3.2 2.1
//Sports
Aron 10.0 9.8 8.8
Ben 9.6 10.0 10.0
Cindy 7.5 6.9 2.1
Thank you