0

I am working on an airline reservation system where a user will be able to select how they want a list to be sorted and displayed. Essentially, I created a list of objects where the object members are the names and codes of a few cities. However, I am not sure how to sort this list by the object members and then display the members of that list. Here is where I create and populate the list.

City Class definition:

#ifndef CITY_H
#define CITY_H
#include <iostream> 
#include <list>

using namespace std;

class City
{
protected:
    string name;
    string code;

public:
    City()
    {
        name = "";
        code = "";
    }
    void setName(string);
    void setCode(string);
    void addCities();
    void displayCities(const list<City> &);

    string getName();
    string getCode();

    friend ostream& operator<< (ostream& , City &);

};

    ostream& operator<< (ostream& , City &);
#endif //CITY_H

void City::addCities()
{
    ifstream cities;
    cities.open("cities.dat");

    list<City> cityList;

    string co = "", na = "";

    while (!cities.eof())
    {
        City c;
        cities >> co;
        cities >> na;

        c.setCode(co);
        c.setName(na);

        cityList.push_back(c);
    }
    displayCities(cityList);
}

Here is the text file with the information I am loading into the list:

ATL Atlanta
ORL Orlando
DFW Dallas/Fort_Worth
NYC New York City
HAW Hawaii
CHI Chicago
LAX Los_Angeles

And this was my attempt at displaying the list:

void displayCities(const list<City> &cityRef)
{
    list<City>::iterator it;
    for (it == cityRef.begin(); it != cityRef.end(); ++it)
    {
        std::cout << (*it) << std::endl;
    }
}

ostream& operator <<(ostream& s, City& c)
{
    s << c.name << c.code;
    return s;
}
tserran
  • 53
  • 1
  • 4
  • 13
  • I imagine `City` is no POD (you should include the definition of it in the question) so you're just printing whatever is pointed by the iterator and not the full content of each element of the list. Also, your title is not accurate, as I do not see any sorting attempts (nor requests). You should also specify what you want to display. – Federico Nov 22 '13 at 22:15
  • `for (it == cityRef.begin();` should be `for (it = cityRef.begin();` and `list::iterator` should be `list::const_iterator`. Apart from that the display code looks OK. (I am assuming you have defined `operator <<` for your `City` class). – john Nov 22 '13 at 22:16
  • Your code will read junk for the last line since it the status of the `ifstream` is only checked before anything is read, see http://stackoverflow.com/questions/4258887/semantics-of-flags-on-basic-ios and many other questions here. – Benjamin Bannier Nov 22 '13 at 22:22

2 Answers2

1

Instead of addCities you really want to overload operator>> for your City class:

struct City { 
    std::string code, name;

    friend std::istream &operator>>(std::istream &is, City &c) { 
      return is >> c.code >> c.name;
    }
};

Then you can read the data (which you're currently doing incorrectly, BTW) like this:

std::ifstream cities("cities.dat");
std::vector<City> CityList{std::istream_iterator<City>(cities),
                           std::istream_iterator<City>());

Then sort something like:

std::sort(cities.begin(), cities.end(), 
          [](City const &a, City const &b) { return a.code < b.code; });

And you can write out the result something like this:

for (auto const &city : CityList) 
    std::cout << city << "\n";

Note that I've made CityList a vector instead of a std::list -- the latter is a mistake much more often than not.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • +1 After that cadence I expected a `std::copy` for the closing output. Nice answer, btw. (and your second `istream_iterator` needs the case of the type fixed). – WhozCraig Nov 22 '13 at 22:27
  • Why would using a list be a mistake? – tserran Nov 22 '13 at 22:45
  • @ShyGuy: Basically because he doesn't seem to be doing anything that takes advantage of the (few) things `std::list` is good at (e.g., lots of inserts or deletes at some predetermined point in the middle of the list). Lacking those, `list` mostly just wastes cache and memory space. – Jerry Coffin Nov 23 '13 at 05:23
0

You could try to use the std::list::sort, as you can see from here

You obviously need to define your comparing method.

Jekyll
  • 1,434
  • 11
  • 13