iamthewalrus
iamthewalrus

Reputation: 47

Reading a file line by line with strings and integers

I'm trying to read the information from the following file:

The Firm
Dell
512
Fundamentals of Computer Graphics
A K Peters, Ltd.
662
The C++ Programming Language
Addison-Wesley Professional
911
Northwest Airlines
Plymouth Toy & Book
96
Lonely Planet: Europe on a Shoestring
Lonely Planet Publications
1324
…

The file lists books with the first line being the Title, second line is Publisher, and third line is Number of pages.It repeats for five books. I'm trying to read the information and store them into the vector in the Library class.

class book

{


public:

    book();


    book(string t, string p, int num);


    string getTitle();
    string getPublisher();
    int getPageNum();


    void setTitle(string t);
    void setPublisher(string p);
    void setPageNum(int num);


    string title;
    string publisher;
    int num_of_pages;

};



  class library
    {
    public:
        vector<book> collection;

        bool contains(string title);

        void addBook(book b);

        void readFile(string fileName);
    }

Here is the readFile function:

   void library::readFile(string fileName)
    {
        ifstream infile;
        infile.open(fileName.c_str());
        if (infile.fail())
        {
            cout<<"Error opening file."<<endl<<endl;
            exit(1);
        }

       book addition;
string line;

while (!infile.eof())
{
    getline(infile, addition.title);
    getline(infile, addition.publisher);
    getline(infile, line);
    addition.num_of_pages=atoi(line.c_str());
    collection.push_back(addition);  
}


        collection.push_back(addition);


    }

One final issue: The output is not working properly. Everything in the file is listed under the title.

ostream &operator <<(ostream& out, const book& b1)
{
    out<<"TITLE: "<<b1.title<<endl;
    out<<"PUBLISHER: "<<b1.publisher<<endl;
    out<<"NUMBER OF PAGES: "<<b1.num_of_pages<<endl;

    return out;
}

Main code:

int i;
                for (i=0; i<book_library.collection.size(); i++)
                {
                    cout<<book_library.collection[i]<<endl;
                }

Output:

TITLE: The Firm
Dell
512
Fundamentals of Computer Graphics
A K Peters, Ltd.
662
The C++ Programming Language
Addison-Wesley Professional
911
Northwest Airlines
Plymouth Toy & Book
96
Lonely Planet: Europe on a Shoestring
Lonely Planet Publications
1324
\311
PUBLISHER: 
NUMBER OF PAGES: 0

Upvotes: 0

Views: 305

Answers (2)

Scott Jones
Scott Jones

Reputation: 2906

You could define an extraction operator for your book class to keep things encapsulated, as well as using the standard built-in extraction operators (>>) to save yourself temp variables and conversions:

std::ifstream & operator>>(std::ifstream & str, book & b)
{
    str >> b.title >> b.publisher >> b.num_of_pages;
    return str;
}

std::ifstream infile;
book addition;
std::vector<book> collection;
while ( infile >> addition)
{
    collection.push_back(addition);
}

Upvotes: 0

Yang
Yang

Reputation: 8180

One simplification could be, since getline returns an istream, to test it directly in the while condition:

while (getline(infile, addition.title)) {
    getline(infile, addition.publisher);
    getline(infile, line);
    addition.num_of_pages = atoi(line.c_str()); // string -> int
    collection.push_back(addition);  // you should push_back in the while loop
}

Upvotes: 1

Related Questions