Input bug

Hi everyone,
In a program I wrote I tryied using char number; cin >> number; to get a number from the user and I wanted to make it bug proof, but when someone type a value longer than one character, it didn't work because I was using a char variable type. So I found on a website that I shoul use char number; getline (cin, number); but there was a compiler problem. Is there a header I am supposed to include for this to work, or did I use it incorrectly?

Thanks in advance.
closed account (j2NvC542)
To my knowledge, getline() only works for strings. It wouldn't make much sense anyway to get the whole line into a one-byte variable. getline() is used when you want to read a string with whitespace.

I don't understand... do you want to read a number from 0 to 9 or a character?
A character.
You are using char variable, it is just for one character.
Try to use int or string instead.
closed account (j2NvC542)
To make it bug proof, you can use a string instead in combination with getline(). That way, there is no way for the user to enter "two" values, because the whole line is read into one variable. Then, you can just read the first character of string with the []-operator.

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main()
{
    std::string s;
    char c;

    std::cout << "Please enter a character: ";
    getline(cin,s);

    c = s[0]; // or s.at(0) if you want to throw an error, if you are out of range.

    return 0;
}
Last edited on
A better alternative to this is the clear the cin flags and ignore anything left in the buffer. An example would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main() {
   std::cout << "Please enter a character. ";
   char myChar;
   std::cin >> myChar;
   std::cin.clear(); // Clear any flags
   std::cin.ignore(80, '\n'); // Used to ignore up to 80 characters or the first \n
   // whichever happens first
   
   // Display the output
   std::cout << myChar;

   return 0;
}


I typed this on my phone and don't have a compiler around so I didn't get to test it, but it should work.
closed account (j2NvC542)
What could set a flag from reading a character? I don't see a possibility for errors here.
Here is an example (it isn't perfect, but it does show you how a failbit can be set):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

int main() {
   int myInt;

   std::cout << "Please enter an int: ";
   std::cin >> myInt;

   // value entered wasn't expected
   while (std::cin.fail()) {
      // Clears cin flags
      std::cin.clear();
      // Ignores characters left in the buffer
      std::cin.ignore(80, '\n');
      std::cout << "Value wasn't an int! Please try again: ";
      std::cin >> myInt;
   }

   std::cout << "myInt = " << myInt;
   return 0;
}
Please enter an int: h
Value wasn't an int! Please try again: apple
Value wasn't an int! Please try again: .5
Value wasn't an int! Please try again: 5
myInt = 5


The program can't handle when you enter a floating point value since it'll just truncate the value after the decimal. However, as you can see, it realized that there was no value before the decimal in .5 and threw a failbit.
closed account (j2NvC542)
Yes ok, I understand that but what does one input into a char variable, to make it set the failbit? You can enter any letter, number and special character. And you can even cin >> more than one char and it won't set a flag.
Are you referring to someone entering a string? Technically they are entering a character, so there is nothing to fail. If you're trying to prevent that person from filling your stream buffer, use the ignore function. I'm not sure where your question is coming from, sorry.
closed account (j2NvC542)
You wrote this code before, in which you are cin.clear()-ing after cin >> myChar;. This implies there may occur an error doing this. I thought you knew a way to cause an error while reading a char. Or did you clear() the stream just in case?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main() {
   std::cout << "Please enter a character. ";
   char myChar;
   std::cin >> myChar;
   std::cin.clear(); // Clear any flags
   std::cin.ignore(80, '\n'); // Used to ignore up to 80 characters or the first \n
   // whichever happens first
   
   // Display the output
   std::cout << myChar;

   return 0;
}
I tried a bunch of ways to get the failbit to be forced, and it's not working for characters so I believe the only way to set a failbit for characters, character arrays, or strings is to manually set the flag. I had tried enter several unicode only characters, but since a character is 1 byte, it still reads the first byte of the unicode character (which I believe is 2 bytes (wide character)).

If anyone else knows of a way to set a failbit while trying to ask for a character from the user, I'd like to know as I never really had to concern myself with it (I always used isalpha or isdigit or isalnum).

@bool
To answer your question, it's more of a habit to put them together, albeit a bad habit. If there is a flag set, you shouldn't just clear it without handling it correctly (much like my last code I posted) and you should only ignore stuff in the buffer if you don't want to read from the buffer before reading from user input (sometimes you want to allow the person to enter all of the information into the buffer at once so your program can just read from that into each variable (think about a CSV)).
closed account (j2NvC542)
Thank you!
Topic archived. No new replies allowed.