This question already has an answer here:
How can I validate an integer input [duplicate]
(1 answer)
Closed 2 years ago.
I am writing a code to take an integer ID from the user which is later validated from a file.
Now when I don't enter a valid input in the cin it doesn't work (obviously). I have attached a sample code below like this:
std::cout << "Enter ID : " << std::endl;
std::cin >> id;
It's simple as that.
Now if I enter an input like a or any other character, I can check for any error using cin.fail()
But if I enter an input like 11a that doesn't seem to work. I have searched a lot on the internet but couldn't find any suitable solution.
Welcome to Stack firstly. Try this
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
I made an output to visualize it. The variable "inputAsInt" would be the one you have to further work with.
Related
How come the loop is returning the message Enter # when done MORE instead of once depending on how many words you enter? EG type a single letter it loops the message Enter # when done but if you type what? it returns it Enter # when done x4 ....the same amount of letter in the word.I am new to c++ coming from c so im confused.Dont worry about other stuff in the code I need help with this. Thank you :)
#include <iostream>
#include <stdio.h>
int main() {
char sup;
while (sup != '#') {
std::cout << "Hi\n";
std::cout << "Enter # when done";
std::cin >> sup;
if(sup == '#') {
std::cout << "Ok you want to go.";
}
}
std::cin.get();
}
Example with std::string
// preferably do not include stdio.h in C++ programs
#include <string>
#include <iostream>
int main()
{
std::string input; // use standard library string class
while (input != "#")
{
std::cout << "Hi\n";
std::cout << "Enter # when done : ";
std::cin >> input;
if (input == "#")
{
std::cout << "Ok you want to go.\n";
}
}
return 0; // <== important to otherwise your program is ill-formed
}
As you set in while loop that (sup != '#'), it will take input character until you type #.
I'm a beginner in C++ and I'm wondering if you can help me.
I'm making a program and error checking is required for this program.
So, how can I accept integer only and ignore other data type?
For example:
int tilenumber;
cin >> tilenumber;
cin.clear();
cin.ignore();
cin >> words;
When my code runs:
Input : 1
hey i wanna dance
Output : ey i wanna dance
///
What I want:
Case 1:
Input : 1
hey i wanna dance
Output : hey i wanna dance
Case 2:
Input : 1e
hey i wanna dance
Output : hey i wanna dance
Why does my code not working?
I tried to solve my problem with my code like above but it's not working.
Thanks.
Read the entire string and utilize the std::stoi function:
#include <iostream>
#include <string>
int main() {
std::cout << "Enter an integer: ";
std::string tempstr;
std::getline(std::cin, tempstr);
try {
int result = std::stoi(tempstr);
std::cout << "The result is: " << result;
}
catch (std::invalid_argument) {
std::cout << "Could not convert to integer.";
}
}
Alternative is to utilize the std::stringstream and do the parsing:
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::cout << "Enter an integer: ";
std::string tempstr;
std::getline(std::cin, tempstr);
std::stringstream ss(tempstr);
int result;
if (ss >> result) {
std::cout << "The result is: " << result;
}
else {
std::cout << "Could not convert to integer.";
}
}
This question already has answers here:
std::cin input with spaces?
(8 answers)
Closed 5 years ago.
I would like to know how to get rid of the '\n' for when I execute cin.get(). For example:
#include <iostream>
int main() {
std::cout << "How many pieces of c: ";
struct c{
std::string name;
int val;
};
int amount;
std::cin >> amount;
c * c1 = new c[amount];
std::cin.get();
for(int i = 0; i < amount; i++){
std::cout << "C Number " << i + 1 << ":" << std::endl;
std::cout << "Please enter the name: ";
c1[i].name = std::cin.get();
std::cout << "Please enter the val: ";
std::cin >> c1[i].val;
std::cin.get();
}
return 0;
}
I've tried using cin.get() to eliminate the '\n' thats last read after my std::cin, but my program only takes in the first name and then executes the rest of the program without letting me continue to type the rest of the name and val values. In short, I want to be able to store the rest of my name and val values. Thanks!
c1[i].name = std::cin.get();
I'm not sure why you used get() instead of operator >>, like you did two lines later. get() reads a single character - meaning, only the first character you type in is saved as name. Everything else is read (most likely unsuccessfully) into val, and then new line character is, just like you intended, digested by the final get().
For reading int, try using getline and stringstream:
std::string input(5, '\0');
int number;
std::getline(std::cin, input);
std::stringstream sstrm(input);
sstrm >> number;
For a name: You can directly use getline
std::string name(30, '\0');
std::getline(std::cin, name);
I'm having a problem with what should be incredibly simple code. I want to take in an integer between 1 and 3 with error checking. It works fine for checking for numbers that are too large or too small, but when a alpha/number combination is entered, it gets stuck in an infinite loop. Suggestions?
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int input;
cout << "\nPlease enter a number from 1 to 3:" << endl;
cout << "-> ";
cin >> input;
while(input< 1 || input> 3){
cout << "\n---------------------------------------" << endl;
cout << "\n[!] The number you entered was invalid." << endl;
cout << "\nPlease re-enter a number from 1 to 3" << endl;
cout << "-> ";
cin >> input;
}
cout << "You chose " << input << endl;
}
The problem is that:
cin >> input;
Will cause the bad bit to be set when you try and read a non numeric value. After that happens any attempt to use the operator>> is silently ignored.
So the way to correct for this is to test if the stream is in a good state and if not then reset the state flags and try and read again. But note that the bad input (that caused the problem) is still on the input so you need to make sure you throw it away as well.
if (cin >> input)
{
// It worked (input is now in a good state)
}
else
{
// input is in a bad state.
// So first clear the state.
cin.clear();
// Now you must get rid of the bad input.
// Personally I would just ignore the rest of the line
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// now that you have reset the stream you can go back and try and read again.
}
To prevent it getting stuck (which is caused by the bad bit being set) read into a string then use a string stream to parse user input. I also prefer this method (for user interactive input) as it allows for easier combination of different styles of reading (ie combining operator>> and std::getline() as you can use these on the stringstream).
#include <iostream>
#include <sstream>
#include <string>
// using namespace std;
// Try to stop using this.
// For anything other than a toy program it becomes a problem.
int main(int argc, char *argv[])
{
int input;
std::string line;
while(std::getline(std::cin, line)) // read a line at a time for parsing.
{
std::stringstream linestream(line);
if (!(linestream >> input))
{
// input was not a number
// Error message and try again
continue;
}
if ((input < 1) || (input > 3))
{
// Error out of range
// Message and try again
continue;
}
char errorTest;
if (linestream >> errorTest)
{
// There was extra stuff on the same line.
// ie sobody typed 2x<enter>
// Error Message;
continue;
}
// it worked perfectly.
// The value is now in input.
// So break out of the loop.
break;
}
}
#include <iostream>
#include <string>
using namespace std;
int validatedInput(int min = 1, int max = 3)
{
while(true)
{
cout << "Enter a number: ";
string s;
getline(cin,s);
char *endp = 0;
int ret = strtol(s.c_str(),&endp,10);
if(endp!=s.c_str() && !*endp && ret >= min && ret <= max)
return ret;
cout << "Invalid input. Allowed range: " << min << "-" << max <<endl;
}
}
int main(int argc, char *argv[])
{
int val = validatedInput();
cout << "You entered " << val <<endl;
return 0;
}
Most of these answers include unnecessary complexity.
Input validation is a perfect time to use a do-while
do{
cout << "\nPlease enter a number from 1 to 3:" << endl;
cout << "-> ";
if(!cin){
cout << "Invalid input"
cin.clear()
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}while(!(cin >> input))
Use numeric_limits<streamsize>::max() to completely clear the
buffer after a failed cin.
Use cin.clear() to reset the fail flag on cin so !cin wont
always evaluate false.
cin.fail() is fine. However some would consider !cin more natural.
from my previous post https://stackoverflow.com/a/43421325/5890809
You declared input as int but when you write an alphanumeric character to input it will try to implicitly convert it into integer. But you error checking does not account for this.
Ur problem can be easily solved by changing your while loop. instead of checking this how about you check
while(input!=1 || input!=2 || input!=3)
I'm writing a simple password program, but the else if statement always applies, even if the password is put in correctly. This works fine if I use a single char instead of an array, and change "hotdog" to 'h', and I think it might have something to do with unseen characters, like a space or return. I was sure cin.ignore() took care of return/enter.
Sorry, I'm fairly new to programming.
#include <iostream>
int main()
{
std::cout << "What is the password?\n" << std::endl;
char password[20] = "NULL";
std::cin >> password;
std::cin.ignore();
std::cout << password << " is your entry?\n";
if (password == "hotdog")
{
std::cout << "Correct!";
}
else if (password != "hotdog")
{
std::cout << "Incorrect!";
}
else
{
}
std::cin.get();
}
Firstly, change char password[20] to string password. This prevents a buffer overflow if they type in more than 20, and it enables you to use == for string comparison.
The code std::cin.ignore() ignores a single character. You want to actually ignore the entire remainder of the line. There is no way to ignore "everything else typed so far" because there may have been characters typed which are still buffered. In practice, it works well to treat input as a series of lines.
The most accurate way to ignore the rest of the line is to ignore all characters up to and including '\n', which appears in the input stream at the end of the line (by definition).
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
which may require #include <limits>. Another way is to read a string and discard it:
std::string t;
std::getline( std::cin, t );
NB. Check your understand of if...else . Once you have if ( condition ), then the next else will already get everything that was not in that condition. It's pointless to actually write else if ( !condition ); and your final else { block can never be entered, because the previous two conditions were exhaustive.
The problem is with how you are using the if-else statement. Try this code out:
#include <iostream>
int main()
{
std::cout << "What is the password?\n" << std::endl;
char password[20] = "NULL";
std::cin >> password;
std::cin.ignore();
std::cout << password << " is your entry?\n";
if (stricmp("hotdog", password) == 0)
{
std::cout << "Correct!";
}
else
{
std::cout << "Incorrect!";
}
std::cin.get();
}
When I take your code and compile it, even the term hotdog does not work properly, I obtain the following:
What is the password?
hotdog
hotdog is your entry?
Incorrect!
As suggested above, a string is a better method and works as intended based on your requirements. Here is sample replacement code that works as intended (with this code spaces are allowed, with the other answers, spaces are not, it all depends what is intended):
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char ** argv)
{
cout << "What is the password?\n" << endl;
string password = "NULL";
getline(cin, password);
cout << password.c_str() << " is your entry?\n";
if (password == "hotdog")
{
cout << "Correct!";
}
else if (password != "hotdog")
{
cout << "Incorrect!";
}
else
{
// Added from original; however, this should never occur
cout << "Else?";
}
system("pause");
return 0;
}
Output of Replacement Code
What is the password?
hotdog
hotdog is your entry?
Correct!
You had to use strcmp() function to compare strings properly in c++,so I added the cstring library:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main(){
string password;
cin >> password;
cout << password << " is your entry?\n";
char hd [7] = "hotdog";
if (strcmp(password.c_str(),hd) == 0){
cout << "Correct!\n";
}
else if (strcmp(password.c_str(),hd) != 0){
cout << "Incorrect!\n";
}
else{
cin.get();
}
}