Thread: Reading multiple files while trying std::find_if in vector

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    203

    Reading multiple files while trying std::find_if in vector

    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
    Last edited by sean_cantab; 04-08-2017 at 08:57 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    I would suggest you highlight interimResults in your IDE, and figure out how it ever gets to be non-empty.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    the problem was on line 45:
    Code:
    for (auto & elem : interimResults)
    the subsequent lambda (lines 48-9) already checks each element of interimResults to see if the name read from file is present in the vector interimResults. the range loop above was not only redundant but, as seen, precluded this check through the lambda and the execution of subsequent commands
    Salem - for the sake of completeness, could you please clarify what you meant by 'highlight interimResults' &c? I'm sorry but my knowledge of the tools of the trade is quite basic. Was it meant to be some sort of debugging exercise? Thanks

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    Highlight - as in search for a word in your IDE and highlight all matching words.Reading multiple files while trying std::find_if in vector-screenshot-2017-04-09-19-05-26-jpg

    But you seem to have found it for yourself anyway.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    Salem - many thanks, got it

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading multiple data from text files
    By Crashie in forum C++ Programming
    Replies: 2
    Last Post: 12-26-2009, 11:37 AM
  2. Writing/Reading multiple files...??
    By audinue in forum C Programming
    Replies: 3
    Last Post: 07-28-2008, 11:14 PM
  3. Reading multiple files in C
    By anjanaanupindi in forum C Programming
    Replies: 8
    Last Post: 10-03-2007, 05:35 AM
  4. reading multiple files in C
    By anjanaanupindi in forum C Programming
    Replies: 1
    Last Post: 10-01-2007, 07:25 AM
  5. reading multiple files
    By marsudhir in forum C Programming
    Replies: 3
    Last Post: 04-16-2003, 01:20 AM

Tags for this Thread