Search code examples
c++vectoroutputcoutranged-loops

Why can't I print contents of vector of objects using a ranged for loop?


I'm a beginner and I solved an exercise involving 10 pie eaters with number of pies eaten set by user input.

  1. 1st task: Display Contestant number and pies eaten - Solved;
  2. 2nd task: Find winners with most pies eaten and list all - Solved;
  3. 3rd task: Find losers with least pies eaten and list all - Solved;
  4. Final task: Sort Contestants and list them in order of most pies to least pies eaten - Partially Solved.

I did everything, no errors or warnings (even stepping over/ into in debugger showed that the vector was sorted correctly), but right when I try to print out the sorted vector, the console screen just won't display anything more (not even the standard message that program execution is finished).

I made a Contestant class with constructor Contestant with two arguments, and declared a vector of objects. Here's the code in main, class header and class solution:

#include <iostream>
#include <vector>
#include "Contestant.h"
using namespace std;

int main()
{
    cout << "Type the number of pies eaten by each of the 10 contestants:" << endl;
    cout << "#1 #2 #3 #4 #5 #6 #7 #8 #9 #10" << endl;

    vector<Contestant> pie_eaters;
    vector<Contestant*> winners; 
    vector<Contestant*> losers; 


    for (int i=0; i<10; i++)
    {
       int pies_eaten;
       cin >> pies_eaten;
       pie_eaters.emplace_back(i+1, pies_eaten);
       cout << "Contestant number " << i+1 << " ate " << pie_eaters[i].GetPancakes() << endl;
    }
    cout << endl;


    FindWinners(pie_eaters, winners);
    ListWinners(winners);

    FindLosers(pie_eaters, losers);
    ListLosers(losers);


    cout << endl;

    SortPieEaters(pie_eaters);

    ListSortedPieEaters(pie_eaters);


}

Class header (edited, just for the sorting and printing out, which are outside the class):

#pragma once
#include <iostream>
#include <vector>

class Contestant
{
private: 
    int pancakes_eaten;
    int number;

public:
    Contestant(int number, int pancakes);

    ~Contestant();
    int GetPancakes() const { return pancakes_eaten; }
    int GetNumber() const { return number; }

};


void SortPieEaters(std::vector<Contestant>& pie_eaters);

void ListSortedPieEaters(std::vector<Contestant> const& pie_eaters);

and Class solution (just the sorting and printing out parts, which are outside the class):

#include "Contestant.h"

using namespace std;

Contestant::Contestant(int number, int pancakes) : pancakes_eaten(pancakes), number(number)
{
}

Contestant::~Contestant() {};


void SortPieEaters(vector<Contestant>& pie_eaters)
{
    while(bool swapped=true)
        {
        swapped = false;
           for (int i = 0; i < static_cast<int>(pie_eaters.size()-1); i++)
           {
                if (pie_eaters[i].GetPancakes() < pie_eaters[i + 1].GetPancakes())
                {
                    swap(pie_eaters[i], pie_eaters[i + 1]);
                    swapped = true;
                }

           }
        }
}

void ListSortedPieEaters(vector<Contestant> const& pie_eaters)
{
    cout << "From most pies eaten, to fewest pies eaten, the results are as follows:" << endl;
    for (auto const& c : pie_eaters)
    {
        cout << "Contestant #" << c.GetNumber() << ": ate " << c.GetPancakes() << " pies" <<endl;

    }
}

And lastly, here's and example output: Output

Everything works fine, but it won't print out the vector or warn there are any issues with it. Tried, everything like passing by constant or non-constant reference, tried writing the body of the function directly in main(avoiding the function), but nothing. And accessing the vector and printing out content was the same as in the case of the winner and losers vectors (even though they are vectors of pointers to the object elements of the pie eaters vector)

What am I doing wrong?


Solution

  • That is because the while loop never ends, since you have initialized the value of swapped = true in the while loop condition, the value of swapped becomes true when the inner for loop ends and the while loop is reprocessed.

    The program never leaves the while loop. thus, the line never executes

    SortPieEaters(pie_eaters); //Executes
    
    ListSortedPieEaters(pie_eaters); //does not execute
    

    You could just do

    bool swapped = true;
    while(swapped)
    {
        swapped = false;
        for (int i = 0; i < static_cast<int>(pie_eaters.size()-1); i++)
        {
            if (pie_eaters[i].GetPancakes() < pie_eaters[i + 1].GetPancakes())
            {
                swap(pie_eaters[i], pie_eaters[i + 1]);
                swapped = true;
            }
        }
    }
    

    Also, I would suggest you to change your sorting logic to something simpler by overloading < in the Contestant class and using std::sort instead