0

I'm using a for loop to read in data from a file and store the values in class members:

while (!bookstxt.eof())
 {
    for (int i = 0; i < x; i++) {

        getline(bookstxt, title);
        getline(bookstxt, author);
        getline(bookstxt, publisher);
        getline(bookstxt, isbn);

        cin.clear();
        cin.ignore(100, '\n');

        bookstxt >> price >> year >> numInStock;

        cout << title << "\n" << author << "\n" << publisher << "\n" << isbn << "\n" << price << "\n" << year << "\n" << numInStock;

        bookList[i].storeBook(title, author, publisher, isbn, price, year, numInStock); 
    }
}

The issue I'm having an issue with the ISBN part - it does what it needs to do correctly the first time around the loop, but on the second time it screws up the isbn and somehow pushes part of it to the next two variables. Here's what the output should look like for the line that breaks

The World is Flat
Friedman, Thomas
Farrar, Straus and Giroux
0-374-29279-5
30.00
2006
12 

Here's what actually happens:

Starting Out with C++
Gaddis, Tony
Pearson
978-0-13-257625-3
129.98
2014
25

The World is Flat
Friedman, Thomas
Farrar, Straus and Giroux
0
-374
-29279
-5
30.00
2006
12
0
-374
-29279

It seems to screw up somewhere around reading the ISBN part. Would appreciate any assistance

  • 4
    At the very least, related: [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Algirdas Preidžius Apr 15 '19 at 14:51
  • 1
    Mixing getline() and >> is error prone. If you use getline for all inputs and then use stringstream to convert inputs to numeric variables (int, double, etc), you will avoid many headaches in life. – Gardener Apr 15 '19 at 15:49

2 Answers2

0

Your cin.ignore() call is in the wrong spot. getline() eats the newline it ends on, so there's nothing to ignore. The >> operator doesn't, so you'll need to ignore the whitespace it leaves in the stream. Move the cin.ignore() to be after you use the >> operator:

while (!bookstxt.eof())
 {
    for (int i = 0; i < x; i++) {

        getline(bookstxt, title);
        getline(bookstxt, author);
        getline(bookstxt, publisher);
        getline(bookstxt, isbn);

        bookstxt >> price >> year >> numInStock;
        cin.ignore(100, '\n');

        cout << title << "\n" << author << "\n" << publisher << "\n" << isbn << "\n" << price << "\n" << year << "\n" << numInStock;

        bookList[i].storeBook(title, author, publisher, isbn, price, year, numInStock); 
    }
}

Furthermore, using .eof() in the loop condition is a Bad Idea.

scohe001
  • 15,110
  • 2
  • 31
  • 51
0

Here is a solution. It doesn't use .eof() in the loop and uses stringstream to extract numerical values.

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

int main () {

    string title, author, publisher, isbn, empty_line;
    string string_price, string_year, string_stock;
    double price;
    int year, stock;
    ifstream bookstxt ("books.txt");
    if(bookstxt.is_open()) {
        while(getline(bookstxt,title))
        {
            getline(bookstxt, author);
            getline(bookstxt, publisher);
            getline(bookstxt, isbn);
            getline(bookstxt, string_price);
            getline(bookstxt, string_year);
            getline(bookstxt, string_stock);
            getline(bookstxt, empty_line);

            stringstream(string_price) >> price;
            stringstream(string_year) >> year;
            stringstream(string_stock) >> stock;

            cout << title << "\n" << author << "\n" << publisher << "\n" << isbn << "\n" << price << "\n" << year << "\n" << stock << "\n\n";
        }
        bookstxt.close();
    } else {
        cout << "Unable to open file";
    }

    return 0;
}

I understood that your original books.txt file should look something like this, correct me if I am wrong:

Starting Out with C++
Gaddis, Tony
Pearson
978-0-13-257625-3
129.98
2014
25

The World is Flat
Friedman, Thomas
Farrar, Straus and Giroux
0-374-29279-5
30.00
2006
12
0

Good luck!

yuko
  • 325
  • 1
  • 8