How to read in a text file into a vector of a class

不想你离开。 提交于 2021-02-10 07:34:47

问题


I need to read in lines from a given text file into a vector of a class of strings. I have this so far but I cannot get them into the vector. I am trying to create a while loop to read in each line of the text file input by the user. I've modified it from the last time, but all it does is read in one thing at a time, splitting Las and Vegas. I also need to push the information from my text file into my Flight vector.

#include "sort.h"
#include "flight.h"
#include "std_lib_facilities_4.h"

vector<Flight> flights;

int main()
{
    Flight fly;
    string flightno, destination, departure, gateno;
    ifstream infile;
    string fileloc;
    cout << "Enter the file you would like to use:\n";
    getline(cin, fileloc);
    infile.open(fileloc);

    /*istringstream foo{"BA036 DALLAS 21:00 A3"};
    Flight bar;
    foo >> bar;
    bar.print();*/

    string line;
    getline(infile, line);
    while (infile >> line)
    {
        istringstream foo{line};
        foo >> fly;
        fly.print();
    }
    cout << endl;
}

The two h files look like this. I don't know if they are built to take in the file lines, so if you have any suggestions, that would be greatly appreciated.

#ifndef SORT_H_
#define SORT_H_
#include "flight.h"
using namespace std;

class Sort 
{
    protected:
        unsigned long num_cmps;                             // number of comparisons performed in sort function

    public:
        virtual void sort(vector<Flight>& data) = 0;        // main entry point
        bool testIfSorted(const vector<Flight>& data);      // returns false if not sorted
                                                            // true otherwise
        unsigned long getNumCmps() { return num_cmps; }     // returns # of comparisons
        void resetNumCmps() { num_cmps = 0; }
};

class SelectionSort:public Sort                             // SelectionSort class
{
    public:
        void sort(vector<Flight>& data);                    // main entry point
};

class BubbleSort:public Sort                                // BubbleSort class
{
    public:
        void sort(vector<Flight>& data);                    // main entry point
};


#endif //SORT_H_

#ifndef FLIGHT_H_
#define FLIGHT_H_
#include "std_lib_facilities_4.h"

and

#ifndef FLIGHT_H_
#define FLIGHT_H_
#include "std_lib_facilities_4.h"

class Flight
{
    string flightno, destination, departure, gateno;
    public:
        void print(){cout << flightno << ' ' << destination << ' ' << departure << ' ' << gateno << endl;}
        friend istream& operator>>(istream& is, Flight& flight);
};

istream& operator>>(istream& is, Flight& flight)
{
    is >> flight.flightno >> flight.destination >> flight.departure >> flight.gateno;
    return is;
}
#endif

This is also the format of the text file that we will be testing.

FLIGHT NUMBER DESTINATION DEPARTURE TIME GATE NUMBER
AA223 LAS VEGAS 21:15 A3
BA036 DALLAS 21:00 A3
AA220 LONDON 20:30 B4
VI303 MEXICO 19:00 B4
BA087 LONDON 17:45 B4
AA342 PARIS 16:00 A7
VI309 PRAGUE 13:20 F2
QU607 TORONTO 8:30 F2
AA224 SYDNEY 8:20 A7
AF342 WASHINGTON 7:45 A3

Sorry for such a long question, any help would be greatly appreciated. Thank you.


回答1:


You should add an Flight::operator>> Note that the istream::operator<< breaks on whitespace. So if you want to use this code you'd need to take the space out of "LAS VEGAS".

For example:

#include <iostream>
#include <sstream>

using namespace std;

class Flight
{
    string flightno, destination, departure, gateno;
    public:
    void print(){cout << flightno << ' ' << destination << ' ' << departure << ' ' << gateno << endl;}
    friend std::istream& operator>>(std::istream& is, Flight& flight);
};

std::istream& operator>>(std::istream& is, Flight& flight)
{
    is >> flight.flightno >> flight.destination >> flight.departure >> flight.gateno;
    return is;
}

int main() {
    istringstream foo{"BA036 DALLAS 21:00 A3"};
    Flight bar;

    foo >> bar;
    bar.print();

    return 0;
}    



回答2:


In the interest of complete overkill and to train my real-life problem solving boost chops:

A few more funky features:

  • it supports destinations with arbitrary content, until it finds a time-like column
  • it checks the header row
  • it interprets the time stamps relative to the current local time (if the departure is more than 30 minutes earlier than current time-of-day, it's assumed to be tomorrow)

Live On Coliru

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/phoenix/function.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

#include <boost/range/algorithm.hpp>

namespace qi = boost::spirit::qi;
namespace bmi = boost::multi_index;
namespace phx = boost::phoenix;

struct Flight {
    std::string id, destination, gate;
    boost::posix_time::ptime departure;

    friend std::ostream& operator<<(std::ostream& os, Flight const& f) {
        return os << "'" << f.id << "'\t'" << f.destination << "'\t" << f.departure << "\t'" << f.gate << "'";
    }
};

using Flights = bmi::multi_index_container<Flight,
      bmi::indexed_by<
        bmi::ordered_unique< bmi::tag<struct by_id>, bmi::member<Flight, std::string, &Flight::id> >,
        bmi::ordered_non_unique< bmi::tag<struct by_destination>, bmi::member<Flight, std::string, &Flight::destination> >,
        bmi::ordered_non_unique< bmi::tag<struct by_departure>, bmi::member<Flight, boost::posix_time::ptime, &Flight::departure> >,
        bmi::ordered_non_unique< bmi::tag<struct by_gate>, bmi::member<Flight, std::string, &Flight::gate> >
      >
  >;

/////////////////////////////////////////////////
// input parsing

BOOST_FUSION_ADAPT_STRUCT(Flight, (std::string,id)(std::string,destination)(boost::posix_time::ptime,departure)(std::string,gate))

boost::posix_time::ptime make_departure(int a_hours, int a_minutes) {
    auto today = boost::gregorian::day_clock::local_day();

    using namespace boost::posix_time;
    auto t_o_d     = second_clock::local_time().time_of_day();
    auto departure = hours(a_hours) + minutes(a_minutes);

    return departure < (t_o_d-minutes(30))
      ? ptime { today + boost::gregorian::days(1), departure }
      : ptime { today, departure };
}

BOOST_PHOENIX_ADAPT_FUNCTION(boost::posix_time::ptime, make_departure_, make_departure, 2)

using It = boost::spirit::istream_iterator;
static const qi::rule<It, std::string()> scol              = +qi::graph;
static const qi::uint_parser<unsigned, 10, 1, 2> time_part = {};
static const qi::rule<It, boost::posix_time::ptime()> dcol = (time_part > ':' > time_part) [ qi::_val = make_departure_(qi::_1, qi::_2) ];
static const qi::rule<It, std::string()> dest_col          = +(qi::graph >> *(+qi::space >> !dcol));

/////////////////////////////////////////////////
int main()
{
    std::cout << "Parsing with local date-time: " << boost::posix_time::second_clock::local_time() << "\n";

    Flights database;
    It first(std::cin >> std::noskipws), last;

    bool ok = qi::phrase_parse(first, last, qi::eps >> 
            "FLIGHT NUMBER" >> "DESTINATION" >> "DEPARTURE TIME" >> "GATE NUMBER" >> qi::eol
            >> (scol >> dest_col >> dcol >> scol) % qi::eol >> *qi::eol
            , qi::blank, database);

    if (ok) {
        std::cout << "Parse success\n";

        boost::copy(database.get<by_id>(),          std::ostream_iterator<Flight>(std::cout << "----- by flight number:\n", "\n"));
        boost::copy(database.get<by_destination>(), std::ostream_iterator<Flight>(std::cout << "----- by destination:\n", "\n"));
        boost::copy(database.get<by_departure>(),   std::ostream_iterator<Flight>(std::cout << "----- by departure time:\n", "\n"));
        boost::copy(database.get<by_gate>(),        std::ostream_iterator<Flight>(std::cout << "----- by gate:\n", "\n"));
    } else {
        std::cout << "Parse failed\n";
    }

    if (first != last)
        std::cout << "Remaining input: '" << std::string(first,last) << "'\n";
}

Which prints:

Parsing with local date-time: 2014-Nov-28 17:58:46
Parse success
----- by flight number:
'AA220' 'LONDON'    2014-Nov-28 20:30:00    'B4'
'AA223' 'LAS VEGAS' 2014-Nov-28 21:15:00    'A3'
'AA224' 'SYDNEY'    2014-Nov-29 08:20:00    'A7'
'AA342' 'PARIS' 2014-Nov-29 16:00:00    'A7'
'AF342' 'WASHINGTON'    2014-Nov-29 07:45:00    'A3'
'BA036' 'DALLAS'    2014-Nov-28 21:00:00    'A3'
'BA087' 'LONDON'    2014-Nov-28 17:45:00    'B4'
'QU607' 'TORONTO'   2014-Nov-29 08:30:00    'F2'
'VI303' 'MEXICO'    2014-Nov-28 19:00:00    'B4'
'VI309' 'PRAGUE'    2014-Nov-29 13:20:00    'F2'
----- by destination:
'BA036' 'DALLAS'    2014-Nov-28 21:00:00    'A3'
'AA223' 'LAS VEGAS' 2014-Nov-28 21:15:00    'A3'
'AA220' 'LONDON'    2014-Nov-28 20:30:00    'B4'
'BA087' 'LONDON'    2014-Nov-28 17:45:00    'B4'
'VI303' 'MEXICO'    2014-Nov-28 19:00:00    'B4'
'AA342' 'PARIS' 2014-Nov-29 16:00:00    'A7'
'VI309' 'PRAGUE'    2014-Nov-29 13:20:00    'F2'
'AA224' 'SYDNEY'    2014-Nov-29 08:20:00    'A7'
'QU607' 'TORONTO'   2014-Nov-29 08:30:00    'F2'
'AF342' 'WASHINGTON'    2014-Nov-29 07:45:00    'A3'
----- by departure time:
'BA087' 'LONDON'    2014-Nov-28 17:45:00    'B4'
'VI303' 'MEXICO'    2014-Nov-28 19:00:00    'B4'
'AA220' 'LONDON'    2014-Nov-28 20:30:00    'B4'
'BA036' 'DALLAS'    2014-Nov-28 21:00:00    'A3'
'AA223' 'LAS VEGAS' 2014-Nov-28 21:15:00    'A3'
'AF342' 'WASHINGTON'    2014-Nov-29 07:45:00    'A3'
'AA224' 'SYDNEY'    2014-Nov-29 08:20:00    'A7'
'QU607' 'TORONTO'   2014-Nov-29 08:30:00    'F2'
'VI309' 'PRAGUE'    2014-Nov-29 13:20:00    'F2'
'AA342' 'PARIS' 2014-Nov-29 16:00:00    'A7'
----- by gate:
'AA223' 'LAS VEGAS' 2014-Nov-28 21:15:00    'A3'
'BA036' 'DALLAS'    2014-Nov-28 21:00:00    'A3'
'AF342' 'WASHINGTON'    2014-Nov-29 07:45:00    'A3'
'AA342' 'PARIS' 2014-Nov-29 16:00:00    'A7'
'AA224' 'SYDNEY'    2014-Nov-29 08:20:00    'A7'
'AA220' 'LONDON'    2014-Nov-28 20:30:00    'B4'
'VI303' 'MEXICO'    2014-Nov-28 19:00:00    'B4'
'BA087' 'LONDON'    2014-Nov-28 17:45:00    'B4'
'VI309' 'PRAGUE'    2014-Nov-29 13:20:00    'F2'
'QU607' 'TORONTO'   2014-Nov-29 08:30:00    'F2'


来源:https://stackoverflow.com/questions/27152521/how-to-read-in-a-text-file-into-a-vector-of-a-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!