lundi 12 octobre 2020

Why does my program terminate when calling this function?

My program is a C++ console program that reads various scores for each team in a tournament from a file, and declares the winner based on the average score (or median if there is a tie in average). An example file would be:

Sea Turtles
11 34 76 58 32 98 43.5 87 43 23 22
Tiger Sharks
85 55 10 99 35 5 65 75 8 95 22
The Angry Piranhas
30 10 80 0 100 40 60 50 20 90 70

The highest and lowest scores for each are dropped before making calculations. With my current program, this example works fine, but as soon as I run it with a file that has 4 or more teams the program goes into the populate_vectors() function´s main loop and instead of returning the value afterwards the whole program just suddenly terminates. This has been the most confusing bug of my life. Here is my full code.

#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
#include <exception>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;

vector<double> temporary_vector;
ifstream inputData;
vector<string> team_names;
vector<double> averages;
vector<double> medians;

int main () {

    bool populate_vectors ();
    void sortvector (vector <double> &vec, int names = 0);
    double mean (vector <double> scores);
    double median (vector <double> scores);

    string intro_message = "This program lets you calculate the winner of a swimming event from a scoring file. You can"; 
    string filename;
    string prompt = "Please specify score file adress. Example: C:\\Users\\marco\\Documents\\cpp_projects\\officialdata.txt";
    
    
    cout << intro_message << endl << prompt << endl;

    bool done = false;
    while (!done) {
        cin >> filename;
        inputData.open(filename);
        if (!inputData.is_open()) { 
            cout << "File not found, try again" << endl << prompt << endl;
            cin.clear(); cin.ignore(); inputData.clear();
            continue; }
           
        done = true;
    }

    bool two_win = populate_vectors();
    
    cout << setprecision(2) << fixed;
    for (int i = 0; i < team_names.size(); i++){
        cout << "Average of " << team_names.at(i) << " is " << averages.at(i) << endl;
        cout << "Median of " << team_names.at(i) << " is " << medians.at(i) << endl << "\n";
    }

    if (two_win){
        if (count(averages.begin(), averages.end(), averages.at(0)) == 1){
            sortvector(medians,true);
            cout << "By median due to average tie, winning team is " << team_names.at(0) << " with a median of " << medians.at(0);
        }
        else
            two_win = false;
        
    }
    if(!two_win){
        sortvector(averages,true);
        cout << "By average, winning team is " << team_names.at(0) << " with an average of " << averages.at(0);
    }
    
    return 0;
}

void sortvector (vector<double> &vec, int names = false){
    double temp;
    string tempp;
    int SIZE = vec.size();
    for (int start = 0; start < SIZE-1 ; start++){
        double maxvalue = vec.at(start);
        int maxindex = start;
        for (int count = start+1; count < SIZE; count++){
            if (vec.at(count) > maxvalue){
                maxvalue = vec.at(count);
                maxindex = count;
            }
        }
        temp = vec.at(start);
        vec[start] = vec.at(maxindex);
        vec[maxindex] = temp;
        if(names){
            tempp = team_names.at(start);
            team_names[start] = team_names.at(maxindex);
            team_names[maxindex] = tempp;
        }
            
    }
}

double mean (vector<double> scores){
    double total = 0;
    for (double i : scores){
        total += i;
    }
    return total/scores.size();
}

double median (vector <double> scores){
    int size = scores.size();
    return scores.at(size/2);
}

bool populate_vectors (){ //this function is the problem
    
    bool twowin_flag = false;
    string line;

    while (getline(inputData, line)){
        
        //odd lines are team names
        team_names.push_back(line);
        
        //even lines are scores (that need to be converted to numeric values first and then sorted/sliced before adding)

        getline(inputData, line);
        
        stringstream iss(line);
        double number;
        while ( iss >> number )
            temporary_vector.push_back( number );
        
        sortvector(temporary_vector);
        temporary_vector.pop_back(); temporary_vector.erase(temporary_vector.begin()); //lowest and highest scores are removed before calculations after sorting
        

        if (find(averages.begin(),averages.end(),mean(temporary_vector)) != averages.end()) //searches for a duplicate to set the "two winners" flag
            twowin_flag = true;

        
        averages.push_back( mean(temporary_vector) );
        medians.push_back( median(temporary_vector) );

        temporary_vector.clear(); //clears tempvector for next round
    }

    //here is the problem
    return twowin_flag;
}

Aucun commentaire:

Enregistrer un commentaire