-2
class Book{
public:
string _title;
string _author;
string _publisher;
Date _published;
float _price;
string _isbn;
int _page;
int _copies;


Book(void);
Book(string, string, string, Date, float, string, int, int);
};

Book::Book(void)
{
 _title = "";
 _author = "";
 _publisher = "";
 _published = 0;
 _price = 0;
 _isbn = "";
 _page = 0;
 _copies = 0;

Where Date is a class including ints for day, month, and year. This generates a no viable overloaded = error.

int main(void)
{
LinkedList myList;
ifstream myFile("sample.txt");

string title;
string author;
string publisher;
Date published;
float price;
string isbn;
int page;
int copies;


while( myFile )
{
getline(myFile,title);
getline(myFile,author);
getline(myFile,publisher);
getline(myFile,published);
getline(myFile,price);
getline(myFile,isbn);
getline(myFile,page);
getline(myFile,copies);

myList.insert_rear(new    Book(title,author,publisher,published,price,isbn,page,copies));
}

myList.print_list();

return 0;

}

For getline published(Date class), price(int), page(int), and copies(int) I'm getting a no matching function call for getline. I know getline is for strings so I expected that error. What can I do instead?

Thank you, and if you need to see more code let me know.

  • `cin >> price;` etc? Usually people learn about `>>` before `getline`. – user253751 Oct 04 '16 at 22:24
  • Not so trivial on this one @immibis. odds are way too good that some of those variable are going to be multi-word. – user4581301 Oct 04 '16 at 22:30
  • Please post a [mcve]. – R Sahu Oct 04 '16 at 22:31
  • @user4581301 What is a multi-word `int`? – user253751 Oct 04 '16 at 22:31
  • 1
    Please, format/indent your code legibly. Avoid [`using namespace std;`](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). The `void` in `int main(void)` and similar is [pointless in c++](http://stackoverflow.com/questions/5587207/why-put-void-in-params). – Dan Mašek Oct 04 '16 at 22:31
  • For the `int` no, but mixing the `>>` and the `getline` needed to handle Author "John Jacob Jingleheimer Schmidt" has a couple caveats to go with it. – user4581301 Oct 04 '16 at 22:36
  • You can always overload `getline` for your classes or overload `operator >>` to read in a class. – Thomas Matthews Oct 04 '16 at 22:56
  • @ThomasMatthews how would you implement that? – William Stone Otworth Oct 05 '16 at 02:43
  • @WilliamStoneOtworth: Create another [getline](http://en.cppreference.com/w/cpp/string/basic_string/getline) function, but have it use your class as the 2nd parameter. Inside the function, put code that reads the class members from the file. – Thomas Matthews Oct 05 '16 at 15:22

1 Answers1

0

One cannot simply std::getline into an int. Seriously. It's harder than walking into Mordor.

A few ways to do this.

One is to intermix std::getline and use of the >> operator. But

myFile >> price;
getline(myFile,isbn);

Won't work because myFile >> price; leaves the end of line in the stream to be gobbled up by getline(myFile,isbn) resulting in an empty string in isbn. Something simple like

char end_of_line;
myFile >> price >> end_of_line;
getline(myFile,isbn);

will do the job, assuming your file strictly adheres to the format.

myFile >> price;
myFile.ignore(numeric_limits<streamsize>::max(), '\n');
getline(myFile,isbn);

is safer. It discards everything up to and including the end of the line.

Sadly you can't do this with published unless you've written an operator>> for Date.

The next good option is to read in everything as a string and then convert it to the appropriate datatype before calling the Book constructor. Something along the lines of

int main()
{
    ifstream myFile("sample.txt");

    string title;
    string author;
    string publisher;
    string published;
    string price;
    string isbn;
    string page;
    string copies;

    while (getline(myFile, title) &&
           getline(myFile, author) &&
           getline(myFile, publisher) &&
           getline(myFile, published) &&
           getline(myFile, price) &&
           getline(myFile, isbn) &&
           getline(myFile, page) &&
           getline(myFile, copies))
    {
        myList.insert_rear(new Book(title,
                                    author,
                                    publisher,
                                    string_to_date(published), // function does not exist 
                                    stof(price),
                                    isbn,
                                    stoi(page),
                                    stoi(copies)));
    }

    return 0;
}

Off topic: Note how all of the getlines are in the while this will not enter the body of the loop unless reading of all of the inputs succeeded.

while( myFile )

tests for goodness at the beginning before all of the values are read. All this tells you is the last thing you read was good. It give no guarantees about the quality of the next things you will read. Currently getline(myFile,title); could fail along with everything after it and you'll build the new Book with the results of invalid reads. Always read, test that you read good information, and only then use what you read.

Probably the best way is to take either of the above two methods and build them into an operator>> for Book.

Then you can

int main()
{
    ifstream myFile("sample.txt");

    Book temp;
    while (myFile >> temp)
    {
        myList.insert_rear(new Book(temp));
    }

    return 0;
}

This even makes it easy to get rid of the dynmaically allocated Book, and that's worth it's weight in gold.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • User4581301, the aforementioned tip works great for price, page, and copies, but will not work for published (date). Any other options for string_to_date(published), // function does not exist ? I have to use published as a class Date for this assignment. Sorry for the formatting errors, first time using this site. – William Stone Otworth Oct 04 '16 at 23:54
  • @WilliamStoneOtworth i totally ignored `Date` because I have no clue what it looks like, how it stores information or what information it stores other than a date. It could be as simple as `Date string_to_date(string datestr) { return Date(datestr) }`. Even if you cannot modify Date, sometimes you can still write a `>>` for it off to the side. More here: http://stackoverflow.com/questions/4421706/operator-overloading (Bookmark that link by the way. It's a real bacon-saver) – user4581301 Oct 05 '16 at 00:13