Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives of getline

Tags:

c++

c++11

getline

#include <iostream>
using namespace std;

class publication {
private:
  string title;
  float price;

public:
  publication() {
    this->title = "";
    this->price = 0.0;
  }

  void getdata() {
    cout << "Enter Title: ";
    getline(cin, title);
    cout << "Enter price: ";
    cin >> this->price;
  }

  void putdata() {
    cout << "Title: " << title << endl;
    cout << "Price: " << price << endl;
  }
};

class book : public publication {
private:
  int pageCount;

public:
  book() { this->pageCount = 0; }

  void getdata() {
    publication::getdata();
    cout << "Enter page count: ";
    cin >> pageCount;
  }

  void putdata() {
    publication::putdata();
    cout << "Page Count: " << pageCount << " pages\n";
  }
};

class tape : public publication {
private:
  float playingTime;

public:
  tape() { this->playingTime = 0; }

  void getdata() {
    publication::getdata();
    cout << "Enter playing time: ";
    cin >> playingTime;
  }

  void putdata() {
    publication::putdata();
    cout << "Playing Time: " << playingTime << " mins\n";
  }
};

int main() {
  book b;
  tape t;
  b.getdata();
  t.getdata();
  b.putdata();
  t.putdata();
  return 0;
}

The first time getline() works perfectly, but the second time it's called, it gets skipped because of some cin >> value; has executed before it. I tried adding a cin.ignore() before getline(), but it either requires me to press enter before giving an input, or skips the first character of the first input.

However, if I add cin.ignore() after the end of every cin >> value; block, it works.

So so I have to suddenly add cin.ignore() everywhere because of one getline()? Or is there any alternative for getline() to take spaces as input?

like image 297
Manish Avatar asked Jun 14 '20 15:06

Manish


1 Answers

Unfortunately the behaviour is fully according to the specification. std::getline works as expected.

You need to read about formatted input and unformatted input to understand why it is implemented as it is.

However, you are looking for solutions. There are basically 3:

  • Use ignore after your formatted input. Unfortunately after every formatted input
  • append one get to your input statement, like (cin >> pageCount).get();. Again, unfortunately after every formatted input
  • Use the std::ws manipulator in the std::getline. Like: getline(cin >> ws, title);. This will eat potential leading whitespaces, including the newline.

Please see the documentation here.

It has the additional advantage that, if the user enters unnecessary whitespace in front of the title, those will be ignored. Example: Input: " This is the title" will read "This is the title", without leading white spaces.

So, what could do is: Use

getline(cin >> ws, title);

and it will work.

Please #include <iomanip>

like image 95
Armin Montigny Avatar answered Nov 05 '22 04:11

Armin Montigny