Why doesn't std::getline block?
Asked Answered
P

2

6

I have this code in an Objective-C class (in an Objective-C++ file):

+(NSString *)readString
{
    string res;
    std::getline(cin, res);
    return [NSString stringWithCString:res.c_str() encoding:NSASCIIStringEncoding];
}

When I run it, I get a zero-length string, Every time. Never given the chance to type at the command line. Nothing. When I copy this code verbatim into main(), it works. I have ARC on under Build Settings. I have no clue what it going on. OSX 10.7.4, Xcode 4.3.2.

It is a console application.

Photoconductivity answered 6/7, 2012 at 2:4 Comment(14)
Have you tried std::cin just in case cin got shadowed?Remaremain
Is there a newline waiting in the buffer?Ewall
Does cin have any error flags set on it?Remaremain
It means there is input waiting to be read on the input. You can empty the input: cin.ignore(std::numeric_limits<std::streamsize>::max())Greaser
@SethCarnegie: No. I never even get a chance to type. It just plods along without allowing me to type.Photoconductivity
@Photoconductivity so, you haven't ever entered any input for the entire lifetime of the program? (Not just counting in the function call)Ewall
@LokiAstari: No dice. Just makes me have to hit enter twice for the input that does work.Photoconductivity
@SethCarnegie: I have. I enter a string, followed by a newline twice. Then I enter an int followed by a newline, float followed by a newline, and then the problem occurs. There are strings being printed between all of the input operations.Photoconductivity
@LokiAstari: That did work! Post as an answer, I'll accept. Thanks.Photoconductivity
99 times out of 100, mysterious I/O behavior is only mysterious because you don't do error checking.Bifurcate
@Photoconductivity the output doesn't matter. When you enter a number, the digits of the number are read, and the newline is not read. So there's a newline waiting to be read. When you use getline, it reads the newline and immediately returns, not allowing you to enter any input because it's already found the end of the line.Ewall
@Hurkyl: I know. Why do you think that socket IO is so ugly? But errors writing to stdout? I hope that never happens...Photoconductivity
@Hurkyl no, this is the classic "reading a string after a number" problem.Ewall
@SethCarnegie: Exactly. Thank you so much. I was beating my head on the keyboard over this one.Photoconductivity
G
9

It means there is input waiting to be read on the input. You can empty the input:

cin.ignore(std::numeric_limits<std::streamsize>::max();
std::getline(cin, res);

If this is happening it means you did not read all the data off the input stream in a previous read. The above code will trash any user input before trying to read more.

This probably means that you are mixing operator>> with std::getline() for reading user input. You should probably pick one technique and use that (std::getline()) throughout your application ( you can mix them you just have to be more careful and remove the '\n' after using operator>> to make sure any subsequent std::getline() is not confused..

If you want to read a number read the line then parse the number out of the line:

std::getline(cin, line);
std::stringstream  linestream(line);

linestream >> value;
Greaser answered 6/7, 2012 at 2:26 Comment(0)
M
2

You can simply do:

cin.ignore();

or use

cin.clear();
cin.sync();

before using getline()

Malave answered 25/8, 2013 at 15:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.