Reputation: 362
I'm using Apple LLVM 3.0 and apparently there is a bug with std::getline
and cin.getline
, which requires the user to push enter twice in order for the std::getline
function to return control back to program. Take this sample code for example:
int main(int argc, const char * argv[]) {
using namespace std;
string str;
cout << "Enter some text: ";
getline(cin, str);
cout << "\nYou Entered: " << str;
return 0;
}
Result:
Enter some text: hello world
I press enter once and the program is still running and waiting for input. I have to push enter again in order for the program to stop asking for input and continue execution.
I've searched for answers and this is apparently a bug in libc++, a similar bug also present in MS VC++ 6.0 (I think).
I tried a workaround by implementing my own getline function using cin.get(char) and returns when it encounters a '\n' or '\r' character. Here is the code below:
std::istream& getline(std::istream &in, std::string &str) {
char ch;
str.clear();
while (in.get(ch) && ch != '\n' && ch != '\r') {
str += ch;
}
return in;
}
Unfortunately I still have the same problem as the first new line character is not returned by in.get hence the program once again hangs waiting for the user to push enter for the second time. Is there any workaround or solution to this problem without resorting to good old C-style fgets(stdin, buffer, bufsize)
.
Upvotes: 1
Views: 1421
Reputation: 16660
I just tried this using the latest release of Xcode and Apple's LLVM, and couldn't reproduce this. (i.e, I only had to hit return once)
$ clang++ --version
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
I built it like this:
$ clang++ -stdlib=libc++ so.cpp
Upvotes: 1
Reputation: 362
This is the only workaround I have found so far. Here's my own version of getline:
std::istream& getline(std::istream &in, std::string &str) {
char chr;
std::ios_base::fmtflags flags = in.flags();
str.clear();
while ((in >> std::noskipws >> chr) && (chr != '\n') && (chr != '\r')) {
str += chr;
}
in.flags(flags);
return in;
}
The above function works as std::getline
is expected to, it returns after the first enter is pushed.
Upvotes: 1