I am trying to practice my input validation in C++. How can i let the program validate the user input when a user is asked to enter a number or string?
Here is a sample of my code.
public:
void CreateProduct() {
inputProduct:
system("cls");
cout << "\n\n\n\n\n\n\n\t\t\t\tPLEASE PROVIDE ACCURATE INFORMATION";
cout << "\n\n\t\tPRODUCT NUMBER: ";
cin >> ProductNumber;
if (!cin) {
cout << "\nPlease provide an integer";
cin.clear();
cin.end;
goto inputProduct;
//when enter a string i should enter this if statement and exit
// to be asked for another entry but am getting stuck in a loop.
}
system("cls");
cout << "\n\n\n\n\n\n\n\t\t\t\tPRODUCT NAME: ";
cin >> ProductName;
system("cls");
cout << "\n\n\n\n\n\n\n\t\t\t\tPRICE: ";
cin >> Price;
system("cls");
}
Please help me understand this input validation.
You can check whether input is number or not by checking ascii value of each character in input .
#include <iostream>
#include <cstring>
#include <string>
int main(void)
{
std::string str;
std::cin>>str;
bool isNumeric = true;
for(size_t i=0;i<str.length();++i)
{
if(str[i]< '0' || str[i] > '9')
{
isNumeric = false;
break;
}
}
if(!isNumeric)
{
std::cout<<"Input is not an integer";
exit(1);
}
return 0;
}
Related
I'm learning C++, so I don't fully understand what's going on with my code here, but from what I've been able to glean, it seems like it could be some kind of buffer issue.
#include <stdio.h>
#include <vector>
#include <iostream>
#include <typeinfo>
using namespace std;
bool stopRun = true;
int height, average, total, count;
vector <int> heights;
int main ()
{
while (stopRun)
{
cout << "Enter a height, or 'end' to quit: ";
cin >> height;
if (typeid(height).name() == "i")
{
heights.push_back(height);
cout << heights[0];
count++;
}
else if (typeid(height).name() == "i")
{
cout << "\nPlease enter an integer: ";
continue;
}
if (count == 5)
{
stopRun = false;
}
}
for (int i = 0; i < heights.size(); i++)
{
total += heights[i];
cout << "\nTotal: " << total;
}
return 0;
}
For some reason, this code will continuously output: "Enter a height, or 'end' to quit: ". In an earlier version, it would output: "Enter a height, or 'end' to quit: Please enter an integer: ".
What I think is going on is that my "cin >> height;" line is pulling in the output from "Please enter an integer: " and treating it as my input, which identifies it as not being of type integer, which starts the infinite loop.
How do I clear the input buffer so that it doesn't bring in cout statements? Or is that even the issue I'm experiencing here?
Thanks in advance!
I suggest to catch the string. If string is not "end" then convert to number inside try/catch
you can use this function at the start of your program fflush(stdin). It will clear your input buffer.
You are attempting to read an int and a string in the same line of code. I suggest you use getline() to read the input and try to convert the string to int.
std::string input;
while (heights.size() != 5) {
cout << "Enter a height, or 'end' to quit: ";
if (std::getline(cin, input)) {
if (input == "end") break;
try {
heights.push_back(std::stoi(input));
}
catch (std::invalid_argument e) {
cout << "\nPlease enter an integer: ";
}
}
}
if (string(typeid(height).name()) == "i")
What you had wrong was the comparison of a pointer and string. Since typeid(height).name() returns a pointer to a c-string with the name for the object.
I'm trying to make a loop to check input strings for numbers only, and negative numbers are allowed. I'm new to programming, this is for a class project.
This code works, to an extent. When it shows the output, it does not show the first number, and does not allow - to be used. I cannot figure out where I'm going wrong in this.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string userInput;
int i = 0;
bool checkInput(int);
int main()
{
do
{
cout << "Please enter a numeric value : ";
string userInput;
cin >> userInput[i];
}
while (!checkInput(userInput[i]));
system("pause");
return 0;
}
bool checkInput(int input)
{
string userInput;
int i;
cin >> userInput;
for (int i = 0; i < userInput.length(); i++)
if (isdigit(userInput[i]))
{
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
return true;
}
else
{
cout << "Please enter a valid numeric value: ";
cin >> userInput[i];
return false;
}
}
Your code doesn't work because you are not utilizing std::string correctly.
When main() prompts the user, it reads into a char of an empty std::string, which is undefined behavior. You should be reading into the std::string itself without calling its operator[] at all. operator>> has an overload for reading std::string values.
checkInput() is just all kinds of wrong. It takes an int as input instead of a std::string, but ignores that input and waits for the user to type in another string value. Then it loops through that string instead of the one read by main(), and only checks the 1st char before exiting. If the char is a digit, checkInput() returns true, and main() exits. Otherwise, checkInput() prompts the user to type in yet another char and then returns false, which then causes main() to prompt the user to type in yet another char. checkInput() does not actually loop through an entire string at all, and does no have any handling for the - character.
Try this instead:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;
bool checkInput(const string &);
int main()
{
string userInput;
cout << "Please enter a numeric value : ";
do
{
cin >> userInput;
if (checkInput(userInput))
break;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
while (true);
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
bool checkInput(const string &input)
{
if (input.empty())
return false;
string::size_type i = 0;
if (input[0] == '-')
{
++i;
if (i == input.length())
return false;
}
do
{
if (!isdigit(input[i]))
return false;
}
while (++i < input.length());
return true;
}
However, the best way to handle this situation is to simply not allow the user to enter non-integer values to begin with. operator>> has overloads for reading integer values, both signed and unsigned types. In this case, reading int values will suffice. Let cin do all of the input validation for you:
#include "stdafx.h"
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int userInput;
cout << "Please enter a numeric value : ";
while (!(cin >> userInput))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
The user should input a double but how would I get the program to ignore a string or a char if they put one in. The problem with my current code is when I put in a string the program will spam and fill the screen with the cout << "What is the length of the rectangle";
double length;
do {
cout << "What is the length of the rectangle: ";
cin >> length;
bString = cin.fail();
} while (bString == true);
do {
cout << "What is the length of the rectangle: ";
cin >> length;
bString = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (bString == true);
This is the code I found that works for my issue.
cin.fail() will not differentiate between integers and floating point numbers.
The best way to check is by using std::fmod() function to check if the reminder is more than zero. if it is then its a floating point number.
Here is the code
#include <cmath>
int main()
{
double length;
std::cout <<"What is the length of the rectangle: ";
std::cin >> length;
if (std::cin.fail())
{
std::cout<<"Wrong Input..."<<std::endl;
} else
{
double reminder = fmod(length, 1.0);
if(reminder > 0)
std::cout<<"Yes its a number with decimals"<<std::endl;
else
std::cout<<"Its NOT a decimal number"<<std::endl;
}
}
Beware that this code will not differentiate between 12 and 12.0.
If the user inputs an invalid data type, cin will fail. You can check using this
double length;
while(true)
{
std::cout << "What is the length of the rectangle: ";
std::cin >> length;
if (std::cin.fail())
{
std::cout << "Invalid data type...\n";
std::cin.clear();
std::cin.ignore();
}
else
{
break;
}
}
I have this snippets of code from my original long program, and as much as it looks simple, it doesn't work correctly! I am brand-new to c++ language, but I know in Java that would be the way to do it (Regardless of the syntax).
Simply put, this should ask the user for an input to answer the following multiplication (5*5), however, it should also check if the user entered a wrong input (not number), keep asking the user again and again... Somehow, it keeps running forever without taking a new input!!
I hope to get, not only an answer, but also a reason for such an error!
int main() {
int userAnswer;
bool isValidAnswer = true;
cout << 5 << " * " << 5 << " = ";
cin >> userAnswer;
cin.ignore();
do {
if (cin.fail()) { //user input is not an integer
cout << "Your answer is not valid! Please enter only a natural number: ";
cin >> userAnswer;
cin.ignore();
} else {
isValidAnswer = false;
}
} while (isValidAnswer);
return 0;
}
Well you need to clear the error state before accepting new input. Call cin.clear() then cin.ignore() before trying to read input again.
I would do something like.
cout << "Enter a number: ";
cin >> number;
while(cin.fail())
{
cin.clear();
cin.ignore(1000, '\n'); //some large number of character will stop at new line
cout << "Bad Number Try Again: ";
cin >> number;
}
First, cin.fail() is not going to adequately check if your answer is a natural number or not with the type set to int (could also be negative).
Second, your boolean isValidAnswer is really checking if it's is an invalid answer.
Third (and most importantly), as another answer suggests, you should put in cin.clear() to clear the failure state, and then followed by cin.ignore(), which will remove the failed string from cin.
Fourth, cin will only check if an int exists somewhere in the string. You'll need to perform your own string comparison to determine if the entire input is a int (see answer below, based on this answer).
Updated:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
bool isNum(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
int main() {
int userAnswer;
string input;
bool isInvalidAnswer = true;
cout << 5 << " * " << 5 << " = ";
while (isInvalidAnswer) {
if (!(cin >> input) || !isNum(input)) {
cout << "Answer is not a number! Please try again:\n";
cin.clear();
cin.ignore();
}
else {
userAnswer = atoi(input.c_str());
if (userAnswer < 0) { //user input is not an integer
cout << "Answer is not a natural number! Please try again:\n";
} else {
isInvalidAnswer = false;
}
}
}
cout << "Question answered!\n";
return 0;
}
I am trying to make a cin where the user can only enter 0 to 1. If the user doesnt enter those numbers then he should get an error saying "Please enter within the range of 0 to 1."
But its not working.
What am i doing wrong?
int alphaval = -1;
do
{
std::cout << "Enter Alpha between [0, 1]: ";
while (!(std::cin >> alphaval)) // while the input is invalid
{
std::cin.clear(); // clear the fail bit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the invalid entry
std::cout << "Invalid Entry! Please Enter a valid value: ";
}
}
while (0 > alphaval || 1 < alphaval);
Alpha = alphaval;
Try this:
int alphaval;
cout << "Enter a number between 0 and 1: ";
cin >> alphaval;
while (alphaval < 0 || alphaval > 1)
{
cout << "Invalid entry! Please enter a valid value: ";
cin >> alphaval;
}
If you want to trap empty lines I'd use std::getline and then parse the string to see if the input is valid.
Something like this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int alphaval = -1;
for(;;)
{
std::cout << "Enter Alpha between [0, 1]: ";
std::string line;
std::getline(std::cin, line);
if(!line.empty())
{
std::stringstream s(line);
//If an int was parsed, the stream is now empty, and it fits the range break out of the loop.
if(s >> alphaval && s.eof() && (alphaval >= 0 && alphaval <= 1))
{
break;
}
}
std::cout << "Invalid Entry!\n";
}
std::cout << "Alpha = " << alphaval << "\n";
return 0;
}
If you want a different prompt on error then I'd put the initial prompt outside the loop and change the inner prompt to what you prefer.
Week one of C++, starting with Peggy Fisher's Learning C++ on Lynda.com.
This is what I came up with. Love to receive feedback.
int GetIntFromRange(int lower, int upper){
//variable that we'll assign input to
int input;
//clear any previous inputs so that we don't take anything from previous lines
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//First error catch. If it's not an integer, don't even let it get to bounds control
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
//Bounds control
while(input < lower || input > upper) {
cout << "Out of Range. Re-enter option: ";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//Second error catch. If out of range integer was entered, and then a non-integer this second one shall catch it
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
//return the cin input
return input;
}
As the exercise was to order Hamburgers, this is how I ask for the amount:
int main(){
amount=GetIntFromRange(0,20);
}