1,105,417 Community Members

While loop getline

Member Avatar
brentr678
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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;}
Member Avatar
DavidB
Posting Pro in Training
433 posts since Jul 2006
Reputation Points: 44 [?]
Q&As Helped to Solve: 33 [?]
Skill Endorsements: 27 [?]
 
0
 

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.

Member Avatar
brentr678
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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.

Member Avatar
NP-complete
Junior Poster
174 posts since May 2010
Reputation Points: 42 [?]
Q&As Helped to Solve: 22 [?]
Skill Endorsements: 4 [?]
 
0
 

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++.

Member Avatar
deceptikon
Eternally Awesome
4,696 posts since Jan 2012
Reputation Points: 1,341 [?]
Q&As Helped to Solve: 689 [?]
Skill Endorsements: 104 [?]
Administrator
Featured
 
0
 

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.

Member Avatar
brentr678
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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.

Member Avatar
NP-complete
Junior Poster
174 posts since May 2010
Reputation Points: 42 [?]
Q&As Helped to Solve: 22 [?]
Skill Endorsements: 4 [?]
 
0
 

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...

Member Avatar
deceptikon
Eternally Awesome
4,696 posts since Jan 2012
Reputation Points: 1,341 [?]
Q&As Helped to Solve: 689 [?]
Skill Endorsements: 104 [?]
Administrator
Featured
 
0
 

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. ;)

Member Avatar
NP-complete
Junior Poster
174 posts since May 2010
Reputation Points: 42 [?]
Q&As Helped to Solve: 22 [?]
Skill Endorsements: 4 [?]
 
0
 

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

Member Avatar
deceptikon
Eternally Awesome
4,696 posts since Jan 2012
Reputation Points: 1,341 [?]
Q&As Helped to Solve: 689 [?]
Skill Endorsements: 104 [?]
Administrator
Featured
 
0
 

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. ;)

Member Avatar
brentr678
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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"

Member Avatar
NP-complete
Junior Poster
174 posts since May 2010
Reputation Points: 42 [?]
Q&As Helped to Solve: 22 [?]
Skill Endorsements: 4 [?]
 
0
 

@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.

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article