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.

Linuxios
  • 34,849
  • 13
  • 91
  • 116
  • Have you tried `std::cin` just in case `cin` got shadowed? – jxh Jul 06 '12 at 02:05
  • Is there a newline waiting in the buffer? – Seth Carnegie Jul 06 '12 at 02:08
  • Does `cin` have any error flags set on it? – jxh Jul 06 '12 at 02:08
  • 1
    It means there is input waiting to be read on the input. You can empty the input: [cin.ignore(std::numeric_limits::max())](http://stackoverflow.com/a/257182/14065) – Martin York Jul 06 '12 at 02:08
  • @SethCarnegie: No. I never even get a chance to type. It just plods along without allowing me to type. – Linuxios Jul 06 '12 at 02:08
  • @Linuxios so, you haven't ever entered any input for the entire lifetime of the program? (Not just counting in the function call) – Seth Carnegie Jul 06 '12 at 02:10
  • @LokiAstari: No dice. Just makes me have to hit enter twice for the input that does work. – Linuxios Jul 06 '12 at 02:11
  • @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. – Linuxios Jul 06 '12 at 02:12
  • @LokiAstari: That did work! Post as an answer, I'll accept. Thanks. – Linuxios Jul 06 '12 at 02:14
  • 99 times out of 100, mysterious I/O behavior is only mysterious because you don't do error checking. –  Jul 06 '12 at 02:14
  • 1
    @Linuxios 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. – Seth Carnegie Jul 06 '12 at 02:15
  • @Hurkyl: I know. Why do you think that socket IO is so ugly? But errors writing to stdout? I hope that never happens... – Linuxios Jul 06 '12 at 02:15
  • 1
    @Hurkyl no, this is the classic "reading a string after a number" problem. – Seth Carnegie Jul 06 '12 at 02:15
  • @SethCarnegie: Exactly. Thank you so much. I was beating my head on the keyboard over this one. – Linuxios Jul 06 '12 at 02:15

2 Answers2

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;
Martin York
  • 257,169
  • 86
  • 333
  • 562
2

You can simply do:

cin.ignore();

or use

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

before using getline()

Hossein
  • 24,202
  • 35
  • 119
  • 224