0

I am having issues with cin.getline(). When I put it into the below program, it is giving an error:

no instance of overload function (ect) matches the argument list

I am also having an issue with my variable nx. The compiler says that it cannot be a constant, but I'm not sure how it is.

Here is my code:

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

//create a class for one book
class Book
{
    //member variables
public:
    string title;
    string author;
    int year;

    //function to print the book details
    void print()
    {
        cout << "Title: " << title << endl;
        cout << "Authot: " << author << endl;
        cout << "Year: " << year << endl;
    }
};

int main()
{
    std::string filename, temp;

    //prompt the user to enter the file name
    cout << "Enter filename: ";
    cin >> filename;

    //open the file
    fstream file;
    file.open(filename.c_str());

    int nx;
    //read the first line of the file to know the number of books
    file >> nx;
    //move to the next line of the file
    std::cin.getline(file, temp);

    //allocate an array of n Book
    
    Book books[nx];
   
    //read the data for n books from the file
    for (int i = 0; i < nx; i++)
    {
        //read file and initialize the books array
        std::cin.getline(file, books[i].title);
        std::cin.getline(file, books[i].author);
        file >> books[i].year;
        //move to the next line of the file
        getline(file, temp);
    }

    //Display the output
    cout << "Books found: " << nx << endl;
    for (int i = 0; i < nx; i++)
    {
        cout << "\nBook " << i + 1 << ":" << endl;
        cout << "Title: " << books[i].title << endl;
        cout << "Author: " << books[i].author << endl;
        cout << "Year: " << books[i].year << endl;
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

1

The 2-parameter std::cin.getline() method does not take a std::fstream or a std::string as parameters. It takes a char* and a std::streamsize instead, as it is meant to fill a char[] buffer. To fill a std::string from a stream, you need to use the standalone std::getline() function instead, eg:

std::getline(file, temp);
...
std::getline(file, books[i].title);
...

As for the "constant" error relating to your nx variable, the problem is on this line:

Book books[nx];

You are trying to declare a fixed-sized array using a size that is not known until runtime. You can't do that in standard C++, an array's size must be known at compile-time instead. Otherwise, you have to use new[] or std::vector to allocate the array dynamically at runtime instead, eg:

Book* books = new Book[nx];
...
delete[] books;

Or:

#include <vector>

std::vector<Book> books(nx);

Demo


On a side note:

When you want to discard content from an istream up to the next '\n' character, you can use the stream's ignore() method instead of std::getline(), that way you are not wasting memory unnecessarily for an unused std::string, eg:

#include <limits>

//move to the next line of the file
//std::getline(file, temp);
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Also, you have defined a print() method in Book, but you are not actually using it. Your final display loop can do this instead:

//Display the output
cout << "Books found: " << nx << endl;
for (int i = 0; i < nx; i++)
{
    cout << "\nBook " << i + 1 << ":" << endl;
    /*
    cout << "Title: " << books[i].title << endl;
    cout << "Author: " << books[i].author << endl;
    cout << "Year: " << books[i].year << endl;
    */
    books[i].print();
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • This worked for line 36 but not line 46 and 47 – zach fisherman May 05 '21 at 00:06
  • It should work just fine for all of your uses of `getline()`. If you are having a particular problem, you need to update your question with the relevant details. – Remy Lebeau May 05 '21 at 00:13
  • it still gives the same error for line 46 and 47 after I have done this – zach fisherman May 05 '21 at 00:17
  • my issue is still the same as the original question I asked. It wasn't fixed. – zach fisherman May 05 '21 at 00:27
  • You should not be getting that error with the code I have given you. `std::getline()` takes an `std::istream&` and an `std::string&` as parameters. `file` is an `std::fstream`, which derives from `std::istream`. A derived object can be assigned to a base-class reference. And `temp`, `Book::title`, and `Book::author` are `std::string`s, so they can all be passed to a `std::string&` reference, obviously. So, if you are still getting errors, then the code you have shown here is not the real code you are actually working with, and you are not applying what I have said to your real code correctly. – Remy Lebeau May 05 '21 at 00:49
  • this is what it is [saying](https://ibb.co/LrqFMWg) – zach fisherman May 05 '21 at 00:54
  • That screenshot is of code that is NOT using the changes I have outlined for you. NONE of this code should be using `std::cin.getline()` at all, only `std::getline()`. And you are still allocating the `books` array incorrectly, too. I think you need to refresh this page, I don't think you are looking at the latest version of my answer. – Remy Lebeau May 05 '21 at 00:55
  • when I take out the cin like you outlined it gives the same error Im focusing on the getline for the moment I will look at the allocation in a minute – zach fisherman May 05 '21 at 00:58
  • It is literally impossible for it to give you the same error, since it would NOT be calling the same method anymore. I suggest you make ALL of the changes I have outlined, and if you are still getting errors after that (I doubt it), then show a screenshot of THAT updated code. Have you looked at the [*working* demo](https://onlinegdb.com/SyJlMu1ud) I provided? – Remy Lebeau May 05 '21 at 01:17