0

I have just started C++ after working with C for almost a year. I'm writing a program for a user to input info about a song. I read that I should use getline() to read strings with spaces. Here is my code:

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

int main()
{
    typedef struct Song
    {
        char title[20];
        char album[20];
        char artist[20];
        int year;
    } song;

    //store song info
    Song Input;
    char inputStr[20];
    int inputYear;
    cout << "Enter the name of a song: ";
    getline(cin, inputStr);
    strcpy(Input.title, inputStr);
    cout << "Enter the album of your song: ";
    getline(cin, inputStr);
    strcpy(Input.album, inputStr);
    cout << "Enter the artist of your song: ";
    getline(cin, inputStr);
    strcpy(Input.artist, inputStr);
    cout << "Enter the year your song was released: ";
    cin >> inputYear;
    Input.year = inputYear;

    //print
    cout << "Song title: " << Input.title << endl;
    cout << "From album: " << Input.album << endl;
    cout << "Artist: " << Input.artist << endl;
    cout << "Released: " << Input.year << endl;
    return 0;
}

My compiler1 throws 3 errors, one for each of the getline() calls, not recognizing getline() despite the fact I have #include <string>. I have looked up sample usage of the getline() function.

Thanks for any help.

1I have wondered if this problem might concern an issue with the standard of C++ that my compiler supports. I did a bit of research and I did not find anything that helped me learn which standard I am using. Here's some info:

I'm using Terminal on Mac. After g++ version:

Configured with: --prefix=/Applications/Xcode.app/Cont.../usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)

These lines seem to be the only ones of use here, but I could give more info. If someone has any idea which standard of C++ this is, whether it's C++11, or C++14, or otherwise, that would also be very helpful. Thanks again.

UPDATE: started from scratch, tried to take as much of your advice as possible while still sticking to some of what I know. No errors and works just as I hoped. Thanks for all your help. New code:

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

struct Song
{
    string title;
    string artist;
    string album;
    string year;
}song;

int main()
{
    Song Input;
    cout << "Song? ";
    getline(cin, Input.title);
    cout << "Artist? ";
    getline(cin, Input.artist);
    cout << "Album? ";
    getline(cin, Input.album);
    cout << "Year? ";
    getline(cin, Input.year);

    cout << "Song: " << Input.title << endl;
    cout << "Artist: " << Input.artist << endl;
    cout << "Album: " << Input.album << endl;
    cout << "Year: " << Input.year << endl;
    return 0;
}
Tanner Causey
  • 17
  • 1
  • 8
  • 2
    _My compiler throws 3 errors_ And those errors were? Most likely they are related to the fact that [`std::getline`](http://en.cppreference.com/w/cpp/string/basic_string/getline) expects 2nd argument to be `std::string`, not `char[]`. Maybe you wanted to call [`cin.getline`](http://en.cppreference.com/w/cpp/io/basic_istream/getline)? – Algirdas Preidžius Jul 10 '17 at 16:39
  • @AlgirdasPreidžius `error: no matching function for call to 'getline'` – Tanner Causey Jul 10 '17 at 16:41
  • 3
    @TannerCausey The compiler is indeed finding `std::getline`, but it can't find an overload that will accept a `char[]` either directly or through an implicit conversion. You need to read the first few lines, not just the first one. – Rakete1111 Jul 10 '17 at 16:43
  • @TannerCausey I suspected as much (typically, such error provides more information, than you copied), and the rest of my comment still applies. – Algirdas Preidžius Jul 10 '17 at 16:44
  • `char` arrays are fine...but if you're using C++ go ahead and jump all in. Use `std::string` instead. There are far too many benefits to list here. – Matt Jul 10 '17 at 16:47
  • I tried to use a `string` variable instead of `char`, but that caused more errors with my calls of `strlen`. If there is a better/simpler way to accomplish this, please let me know. – Tanner Causey Jul 10 '17 at 16:51
  • 1
    _"I read that I should use getline() to read strings with spaces. Here is my code:"_ More accurately, use getline() to read lines. – Lightness Races in Orbit Jul 10 '17 at 17:01
  • @TannerCausey For starters, should read a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). SO is not tutorial site. Have a look through [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string) documentation: what you wanted to use instead of `strlen` is [`length`](http://en.cppreference.com/w/cpp/string/basic_string/size) method on a `std::string` object. – Algirdas Preidžius Jul 10 '17 at 17:03
  • @AlgirdasPreidžius I am doing this as practice for a course I am starting in the fall. As for the `strlen` part, I meant `strcpy` - I apologize. – Tanner Causey Jul 10 '17 at 17:20
  • @TannerCausey If you want to assign strings, use the assignment operator, which is provided for `std::string`. From what I can see - you are trying to learn C, while claiming, that you are learning C++. – Algirdas Preidžius Jul 10 '17 at 17:35

2 Answers2

5

The version of getline you are using takes a std::string as a parameter, not an array of char. If you want to use an array of char (and you shouldn't), you need to use the member function version:

    cin.getline( some_char_array, array_size );
0

I would switch from using char arrays to using string's everywhere. For example I would do your code like this:

#include <string>
#include <iostream>

struct Song{
    std::string title;
    std::string album;
    std::string artist;
    int year;
};

int main()
{    
    //store song info
    Song Input;
    int inputYear;
    std::cout << "Enter the name of a song: ";
    getline(std::cin, Input.title);
    std::cout << "Enter the album of your song: ";
    getline(std::cin, Input.album);
    std::cout << "Enter the artist of your song: ";
    getline(std::cin, Input.artist);
    std::cout << "Enter the year your song was released: ";
    std::cin >> Input.year;

    //print
    std::cout << "Song title: " << Input.title << '\n';
    std::cout << "From album: " << Input.album << '\n';
    std::cout << "Artist: " << Input.artist << '\n';
    std::cout << "Released: " << Input.year << std::endl;
    return 0;
}

My preference is to not use using namespace std; but there's nothing wrong with it. Notice that using strings directly I don't need to copy things. I can use getline to do all that for me. I also don't need to worry about overrunning the size of the char array because string does that for me as well.

Matt
  • 2,554
  • 2
  • 24
  • 45