Im trying to write a program that simply takes a string input and reverses it. I want the program to repeat itself by asking the user then starting over. The problem im having is that when the program first runs, the getline function works correctly but then after the program repeats itself it seems to skip the getline. Any ideas to why this is? The code is below...thanks for all replys!

#include <iostream>
#include <string>
using namespace std;
void swap(char &p1, char &p2);
int main(){
    char repeat = 'y';
while (repeat == 'y'){
    string line;
    char *p1, *p2;
    cout << "Enter a line\n";
    cin.ignore(cin.rdbuf()->in_avail(),'\n');
    getline(cin, line);
    p1 = &line[0];
    p2 = &line[(line.length()-1)];
for (int i = 0; i<(line.length()/2);i++){
    swap(*p1, *p2);
    p1 = p1+1;
    p2 = p2-1;}
    cout << line << endl;
    cout << "Do you want to repeat? (y/n) \n";
    cin >> repeat;}}
void swap(char &p1, char &p2){
    char temp = p1;
    p1 = p2;
    p2 = temp;}

Dani AI

Generated

Mixing formatted extraction (operator>>) with getline is the usual cause here: reading repeat with cin >> repeat leaves the newline in the input buffer, so the next getline immediately returns an empty string. ’s debug idea is useful to confirm that. Also note ’s point that cin.rdbuf()->in_avail() is unreliable on GCC and behavior can differ by platform (as observed), so don’t rely on that to “flush” the stream.

Two simple, robust approaches that avoid the problem:

  • Always use getline for the yes/no reply (read a small string and inspect the first non-whitespace character).
  • Or skip any leftover whitespace before calling getline by using the std::ws manipulator.

Example (illustrative):

string answer;
getline(cin, answer);                 // read the reply line, then check answer[0]
...
// or skip leading whitespace before reading the main line:
getline(cin >> ws, line);

A few extra cautions and tips: check line.empty() before taking &line[0] or indexing — dereferencing data on an empty string is undefined behavior. Since C++11 string storage is contiguous, but it’s still cleaner and safer to use std::reverse(line.begin(), line.end()) or index-based swapping rather than raw pointers. Compile with warnings enabled (e.g., -Wall) and test with sanitizers/valgrind if you suspect undefined behavior. If you prefer ignore, use it with a very large count rather than in_avail(); otherwise prefer the getline/ws pattern for predictable, cross-platform behavior.

Recommended Answers

All 11 Replies

Right after the input line in the loop (line # 21), you should output the repeat variable, just to make sure the program thinks it is what you think it is.

I did that to test it and yes it is taking the correct variable letter. I know its repeating correctly because it goes over the cout << enter a line sentenance but then doesnt allow for any input.

Which compiler? And which platform?
It works as its supposed to in Visual Studio 2010 (i used the command line tool) on a Windows machine.

I think, if you're on *nix, along with that cin.ignore(cin.rdbuf()->in_avail(),'\n'); you also need a cin.ignore(cin.rdbuf()->in_avail(),'\r');

I'm not sure, but intuition tells me that it has to do with the platform specific implementation of \r and \n by C/C++.

cin.ignore(cin.rdbuf()->in_avail(),'\n');

There's no guarantee that in_avail() will give you a meaningful value. In fact, GCC always returns 0 by default. The correct way to use ignore() would be asking for up to the maximum possible stream buffer size:

cin.ignore(numeric_limits<streamsize>::max(), '\n');

There's a sticky that highlights all of the issues and potential solutions. You should read it.

Yea its a GCC complier. I think your right about it being the compiler thats the issue. I ran it in Visual Studio using the cin.ignore and it worked perfectly but still did not work in the unix enviornement using the GCC compiler.

Did you try ignoring the \r as well?

Try to use deceptikon's advise of using ignore with a large value (like 100 or numeric_limits<streamsize>::max()) and ignore the \r as well and see if it runs on unix...

Did you try ignoring the \r as well?

That accomplishes nothing. Regardless of the newline configuration on the system, it will be appropriately converted by the standard I/O library such that the only thing you ever see is '\n'.

On Unix it's a non-issue anyway because '\n' is the native newline configuration to begin with. Other systems like Windows (which uses CRLF or "\r\n") and old Mac OS prior to version 10 (which uses '\r') do a little more work.

As an example of how the standard library works, here's a buffer filling routine that does newline compaction for text mode streams on Windows (starting at line 965). It's for the C standard library, but C++ does something similar way under the hood. ;)

Oh! I see... then what's the workaround for unix?

then what's the workaround for unix?

Workaround for what?

As concerns the original problem, I'm all but convinced that it's due to in_avail() being completely unreliable for the purpose of flushing the input buffer. The workaround in that case would be to use the correct solution in the first place, which I highlighted in my first reply. ;)

Well the ignore "\n" worked when i used it in Visual Studio but still doesnt not in the unix enviornement using GCC. Neither does the ignore "\r"

@brent: did you use the correct usage of in_avail() as highlighted by deceptikon in his first post?

Also, check out that sticky (and read it full, because somewhere down in the comments section someone mentioned that using pause2 instead of pause may do the trick in unix) and try to implement Narue's final solution and see how that turns out in unix...don't forget to implement that trick as well...

Well, try out the correct usage of in_avail() first...and if that works you may skip Narue's full implementation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.