I'm having trouble with this section my code and am hoping that you can help me diagnose and solve the problem. I'm not sure if it makes a difference, but I compile and run my code in Cygwin.

The problem:
At run time when the program asks for the user input I can input somethimg like: "Guybrush Threepwood Throe" and the code will run just fine, but if I type the same thing and then use the left arrow button to move the cursor back over the input to make a correction (for instance to change the third word of the input from "Throe" to "Three"), the program will ignore (or seem to ignore) all of my "cin.ignore(1000, '\n');" and "cin.getline(input1, 31, '\n');" commands. I'm aware that you're not technically supposed to use the arrow keys in Cygwin, but I'm trying to make my code fool-proof.

Why does this happen, and assuming the user will eventually use those arrow keys, how can I prevent the undesired side-effects?

#include <cstdlib>
#include <iostream>
using namespace std;

int main ()
{
  char input1[31];
  char default1[31] = "                              ";
  int success = 0;
  int tries = 0;
  while ((success != 0) && (tries < 4))
  {
     cout << "[By what name shall you be known? Max: 30 Characters]" <<   endl;
     cout << ":" << endl;
  // Point of possible conflict follows immediately
     cin.getline(input1, 31, '\n');
     if (((input1[0] > 64) && (input1[0] < 91)) || ((input1[0] > 96) && (input1[0] < 123))) 
        success = 1; // Success = 1 if input1 starts with a letter.
     else
     {
        cout << "What kind of name doesn't begin with a letter?" << endl;
        cout << "(Type a name that starts with a letter.)" << endl;
        tries++;
     }
  }

  if (tries >= 4)
  {
     char guybrush[31] = "Guybrush";
     strcpy (input1, guybrush);
     cout << "Fine. I'm going to assume your name is Guybrush." << endl;
  }


  cout << "Some text here..." << endl;
  cin.ignore(1000, '\n');     // Used as a pause function
  cout << "Some more text here..." << endl;
  cin.ignore(1000, '\n');

  strcyp (input1, default1);
  cout << "Input command." << endl;
  cout << ":";
  cin.getline(input1, 31, '\n');
  return 0;
}

Thank you for your input.

Salem commented: Excellent first post - code tags, environment, statement of problem and example code. Everyone else should learn from this! +22

Recommended Answers

All 7 Replies

Excellent first post - code tags, environment, statement of problem and example code. Everyone else should learn from this!

> strcyp (input1, default1);
Does this compile?
Isn't it supposed to be strcpy() ?

> the program will ignore (or seem to ignore) all of my "cin.ignore(1000, '\n');" and
> "cin.getline(input1, 31, '\n');" commands.
Or they could be returning error.
Check the return result to see if this is the case.

> strcyp (input1, default1);
Does this compile?
Isn't it supposed to be strcpy() ?

Sorry about this one. I had to retype the code on another computer to put it online; so no.. it probably wouldn't compile. Additionally, on line 14, a correction would have to be made to cause the program to go into that while loop.

It would be changed from:

while ((success != 0) && (tries < 4))

to

while ((success == 0) && (tries < 4))

> the program will ignore (or seem to ignore) all of my "cin.ignore(1000, '\n');" and
> "cin.getline(input1, 31, '\n');" commands.
Or they could be returning error.
Check the return result to see if this is the case.

I checked the value of input1 by adding the following code after the if-statement that starts on line 30.

cout << "input1 =" << input1 << "!" << endl;

I experimented with different input and arrow key combinations, and came to some realizations.

1. I started with the standard input that I used for all of the debugging:
Guybrush Threepwood T2345
2. When I used any left-right combination that started with the left arrow, the output always came out the same (regardless of whether or not I replaced characters.):

input1 =Guybrush Threepwood T234ome text here...
Some more text here...

3. When I used any left-right combination that started with the right arrow, I got:

input1 =Guybrush Threepwood T2345 ome text here... 
Some more text here...

I didn't bother with the up or down arrows because it made things way more complicated.

I'm sorry that this this getting more complicated, but I thank you for your patience and responses.

So if you have

while ( cin.getline(input1, 31, '\n') ) {
  cout << "--" << input1 << "--" << endl;
}
if ( cin.fail() ) {
  cout << "Failed" << endl;
}
if ( cin.eof() ) {
  cout << "EOF" << endl;
}
if ( cin.bad() ) {
  cout << "bad, very bad" << endl;
}

If you use an arrow key, what happens here?
- loops a few times, then prints one of the exit messages?
- loops a few times, printing various fragments of the edited input, then goes back to waiting.

http://www.cppreference.com/wiki/io/fail

To get out of the loop, press ctrl-d, and you should see EOF printed.

If the code keeps in the loop, but prints various fragments of the line in several attempts, you should be able to recover.

Oh, and please find a way of copying the code accurately (pen drive, email yourself, whatever). It'll save a lot of confusion in the long run.

while ( cin.getline(input1, 31, '\n') ) {
  cout << "--" << input1 << "--" << endl;
}
if ( cin.fail() ) {
  cout << "Failed" << endl;
}
if ( cin.eof() ) {
  cout << "EOF" << endl;
}
if ( cin.bad() ) {
  cout << "bad, very bad" << endl;
}

This is a clever test. Thanks for this insight.

If you use an arrow key, what happens here?
- loops a few times, then prints one of the exit messages?
- loops a few times, printing various fragments of the edited input, then goes back to waiting.

When I use the arrow keys it prints "Failed." And according to the link "Once set, the fail state will make all other operations on the stream fail instantly, until the error state is cleared with the clear function." (http://www.cppreference.com/wiki/io/fail)

So it sounds like the fail flag is being tripped, would which apparently cause my program to go haywire. I'm looking around and can't seem to find any information on the "clear function."

Oh, and please find a way of copying the code accurately (pen drive, email yourself, whatever). It'll save a lot of confusion in the long run.

I shall try. Again, thanks for your patience and input.

http://www.cppreference.com/wiki/io/clear

link to the clear() method of input stream. It's under the C++ I/O link on the main page, then click on clear.

This site deserves to be on your list of favorites, if it isn't already.

Make a function like this (with iostream included and the std namespace):

ostream & Flush (ostream & myStream)
{
myStream.clear();
myStream.ignore(myStream.rdbuf()->in_avail());
return myStream;
}

Then call it for whatever stream you want to clear, and it supports chaining. ie Flush(cin) >> iInput;

http://www.cppreference.com/wiki/io/clear
This site deserves to be on your list of favorites, if it isn't already.

It definitely is now.

Make a function like this (with iostream included and the std namespace):

ostream & Flush (ostream & myStream)
{
myStream.clear();
myStream.ignore(myStream.rdbuf()->in_avail());
return myStream;
}

Then call it for whatever stream you want to clear, and it supports chaining. ie Flush(cin) >> iInput;

I actually had a lot of trouble trying to figure out how exactly to implement the code, and it took three webpages and this thread for the information to make a modicum of sense to me. I came up with this seemingly simple function:

void clear (ios::iostate flags = ios::goodbit);

which I call using the following segment of code, which is partially borrowed from Salem's code:

if ( cin.fail() )
{
  cout << "Failed." << endl;
  cout << "Please do not use the arrow keys." << endl;
  cin.clear();
}

The sources that proved helpful to me are listed here:
http://www.cppreference.com/wiki/io/clear
http://www.cplusplus.com/reference/iostream/ios_base/iostate.html
http://www.cplusplus.com/reference/iostream/ios/clear.html

It seems that this problem is solved, so thank you to everyone who contributed time and information to my code.
-- LordoftheFly

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.