0

I'm new to code and this website, so please forgive me if I'm overlooking something obvious. I've been trying to write a short little game in c++, and I need to take in user input. I want to take in more than one word so the cin>> command my book recommends is right out. The best thing I have found through research is the getline(cin,var); command. I can get this to easily work in small scale tests, but when I implement it in to my 500 line game, it never works. It will skip right over that bit of code without waiting for user imput, and set the variable to a blank space. I won't include the whole code obviously, but here is the bit in question, and my headers.

#include <cstdlib>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
string poemend;
int heading;  

int poem()
{
    system("CLS");
    cout<<"This  poem is almost done, you just can't seem to find the perfect last word.\n";
    cout<<"You can see several of your discarded endings. Most recently, 'pain'.\n\n";
    cout<<"How about another go?\n>";
    getline(cin,poemend);
    system("CLS");
    cout<<"The Prophet's old parrot spoke much of all things,\n";
    cout<<"but when asked about love, squawked only ";
    cout<<poemend<<" .\n\n";
    Sleep(6000);
    cout<<"You decide it could still use some work";
    Sleep(3000);
    heading = 6;
}

Again, this works perfectly if I take this in to a new blank page, so I'm really not sure what is getting in the way. I will be happy to answer any questions about the code and post more helpful bits of it if needed. Thank you so much for taking the time to read this!

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Hammurabi8
  • 35
  • 1
  • 4
  • Pls use a little indentation – Ed Heal Jan 25 '14 at 03:10
  • The code that you're not showing us is the problem. – David G Jan 25 '14 at 03:21
  • The code that you're showing us here has no problem. Can you post more code that has to do with the stream? – David G Jan 25 '14 at 03:29
  • If you use a `cin` at any point before the `getline`, the end-of-line will still be waiting to be read in and the `getline` will happily take it without waiting for any more input. – Mark Ransom Jan 25 '14 at 03:55
  • @MarkRansom Not sure if I understand what you mean - `std::getline` doesn't take or extract new lines (by default). It uses it as a delimiter for input. So if a newline is still left in the beginning of the stream, `std::getline` will become nonoperational until it is discarded. – David G Jan 25 '14 at 04:02
  • From http://www.cplusplus.com/reference/string/string/getline/ : If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it. – Mark Ransom Jan 25 '14 at 04:08
  • @MarkRansom That's exactly what happens, but that's not what I meant. I said the _beginning_ of the stream. `std::getline` doesn't discard leading whitespace so the extraction can be performed. So it will set `ios_base::failbit` in the stream. Only a subsequent read attempt (after clearing the stream state) can work. – David G Jan 25 '14 at 04:16
  • No, `getline` will read everything up to the newline (even if it's 0 characters) and it *won't* set `failbit` except under extraordinary circumstances. I'm not even sure it's possible. – Mark Ransom Jan 25 '14 at 04:33
  • I don't quite understand all this, but @MarkRansom, are you saying if I used the cin>> command earlier in the program, it could mess it up? The beginning still use that, as it only needs one word. If I change all that, would that help? – Hammurabi8 Jan 25 '14 at 06:17
  • @MarkRansom Yeah, you're right about the stream state thing, but `std::getline` *can* set failbit (for example on uninitialized string streams or file streams). – David G Jan 25 '14 at 13:57

2 Answers2

0

Sometimes flushing the input buffer is magic. This may or may not be the case in your senario, but try this code.

cin.ignore( cin.rdbuf()->in_avail() );
cin.getline(cin,poemend);
cin.clear();

Essentially wrapping your getline with the ignore code and cin.clear.

Jeff.Clark
  • 599
  • 1
  • 5
  • 27
  • error: no matching function for call to 'std::basic_istream::getline(std::istream&, std::string&)'| What does that mean? – Hammurabi8 Jan 26 '14 at 19:08
  • It means that the getline function is not overloaded to handle the variable datatypes you currently have in the function. Wifey and I are going to have date night soon, so I cannot do a ton of research for you to make it work, but try this page. http://www.cplusplus.com/reference/string/string/getline/ – Jeff.Clark Jan 27 '14 at 05:13
  • It is good that you are getting an error now, because that means flushing the input buffer has fixed your initial problem of the getline being skipped over entirely. Now you just need to figure out what you need to put into the getline() function. – Jeff.Clark Jan 27 '14 at 05:15
0

You still have a newline which is the residue of a previous unformatted input operation. You have to discard it using std::ws. Moreover, always check if your input succeeded:

if (std::getline(std::cin >> std::ws, poemend))
//               ^^^^^^^^^^^^^^^^^^^
David G
  • 94,763
  • 41
  • 167
  • 253