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?
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?
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;
}
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.
#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.
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.
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)).