0

I'm creating a program that reads the author, title, and number of volumes from a file and prints out labels,

(ex. Adams A Complete History of the World Volume 1 of 10

Adams A Complete History of the World Volume 2 of 10 etc.)

To make it read properly and not infinitely loop, I had to change all of my variable to string. However, for future reference to the volume number, I need it to be int so I can compare the amount. My ideas for furthering the code with a do-while loop are commented in to show why I'd like vnum to have int value.

#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{

        ifstream fin;
        string author;
        string title;
        string vnum;
        int counter=1;

   fin.open("publish.txt", ios::in);


   while (!fin.eof())
   {
       getline(fin, author);
       getline(fin, title);
       getline(fin, vnum);

       //do
       //{
           cout << author << endl;
           cout << title << endl;
           cout << "Volume " << counter << " of " << vnum << endl;
           cout << endl;
           //counter++;
       //} while(counter < vnum);

   }
   fin.close();
   return 0;

}

File I'm reading from:

Adams

A Complete History of the World

10

Samuels

My Life of Crime

2

Baum

Wizard Stories

6

  • Possible duplicate: https://stackoverflow.com/questions/14715025/how-can-i-convert-c-str-to-int. – Eugene Sep 12 '19 at 17:45
  • 1
    or see: https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction – NathanOliver Sep 12 '19 at 17:45
  • Keep an eye on `while (!fin.eof())`. [It's not your friend.](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – user4581301 Sep 12 '19 at 17:47

1 Answers1

1

First of all, avoid use of

while (!fin.eof())

See Why is “while ( !feof (file) )” always wrong? to understand the problems it would cause.

Coming to your task, I would suggest:

  1. Create a struct to hold the data.
  2. Add a function to read all the members of the struct from a std::istream.
  3. Add a function to write all the members of the struct to a std::ostream.
  4. Simplify main to use the above.

Here's what I suggest:

struct Book
{
   std::string author;
   std::string title;
   int volume;
};

std::istream& operator>>(std::istream& in, Book& book);
std::ostream& operator<<(std::ostream& out, Book const& book);

That will help simplify main to:

int main()
{
   ifstream fin;
   Book book;

   // Not sure why you would need this anymore.
   int counter=1;

   fin.open("publish.txt", ios::in);

   while  ( fin >> book )
   {
      cout << book;
      ++counter;
   }

   return 0;
}

The functions to read and write a Book can be:

std::istream& operator>>(std::istream& in, Book& book)
{
   // Read the author
   getline(in, book.author);

   // Read the title
   getline(in. book.title);

   // Read the volume
   in >> book.volume;

   // Ignore rest of the line.
   in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

   return in;
}

std::ostream& operator<<(std::ostream& out, Book const& book)
{
   out << book.author << std::endl;
   out << book.title << std::endl;
   out << book.volume << std::endl;

   return out;
}
R Sahu
  • 196,807
  • 13
  • 136
  • 247