How to allow only positive integer input from user? - c++

I have been trying to only allow positive integer input into my program. But works it is getting past with the character input and negative integers, decimal numbers. Any ideas how to fix that?
#include <iostream>
using namespace std;
int main()
{
int row, col, i, i1, j, test;
double n;
test = 0;
while (test == 0)
{
cout << "Enter the number of rows: " << endl;
cin >> row;
if (cin.fail() || row <= 0 || !(row == (int)row))
{
cout << "\nEntered value is wrong!";
printf("\n");
cin.clear();
cin.ignore();
test = 0;
}
else { test = 1; }
}
}

I have been trying to only allow positive integer input into my
program.
You can easily check it with the help of std::isdigit, if you take the user input as a string instead of an integer.
take the user input as a string.
for each character in the string, check whether it is a digit (using std::isdigit).
if any of the char's in the user input(which is a string) is not a valid digit, return the boolean = false.
if its true for all chars, the input is an integer and you can convert it back to integer using std::to_string.
Following is a sample code:
SEE LIVE
#include <iostream>
#include <cctype> // std::isdigit
#include <string>
#include <vector>
bool isInteger(const std::string& input)
{
for (const char eachChar : input)
if (!std::isdigit(eachChar))
return false; // if not a digit, return False
return true;
}
int main()
{
std::vector<std::string> inputs{ "123", "-54", "8.5", "45w" }; // some inputs as strings
for(const std::string& input: inputs)
{
if (isInteger(input))
{
// apply std::stoi(input) to convert string input to integer
std::cout << "Input is a valid integer: " << input << std::endl;
}
else { std::cout << input << " is not a valid integer!\n"; }
}
}
output:
Input is a valid integer: 123
-54 is not a valid integer!
8.5 is not a valid integer!
45w is not a valid integer!

This is what you probably want (demo):
#include <iostream>
#include <limits>
int main()
{
using namespace std;
int n;
while ( !( cin >> n ) || n < 0 )
{
cin.clear();
cin.ignore( numeric_limits<std::streamsize>::max(), '\n' );
}
//...
return 0;
}

Related

I want to take a number from the user and if he type a character or anything else i want him to enter the number again

int x;
if(cin >> x)
cout << "True" << endl;
else
{
cin >> x;
}
It supposes to let me enter the number again but it's end the program without taking the number again
A simple solution is to get the input as string, use regex to check if it's a number and if it is convert it to an int, otherwise ask for input again. Here's an example:
#include <iostream>
#include <string>
#include <regex>
int main() {
std::regex rx(R"((?:^|\s)([+-]?[[:digit:]]+(?:\.[[:digit:]]+)?)(?=$|\s))");
std::string line;
int n;
while ( std::getline(std::cin, line) ) {
if ( std::regex_match(line, rx) ) {
// Input is number
n = std::stoi( line );
std::cout << n << "\n";
break;
}
}
return 0;
}

How to make user input numbers only in C++?

So far, this is my code:
while(bet > remaining_money || bet < 100)
{
cout << "You may not bet lower than 100 or more than your current money. Characters are not accepted." << endl;
cout << "Please bet again: ";
cin >> bet;
}
It works fine but I'm trying to figure out how to make it loop if the user inputs anything that isn't a number as well.
When I press a letter or say a symbol/sign, the code just breaks.
Using the function
isdigit()
This function returns true if the argument is a decimal digit (0–9)
Don't forget to
#include <cctype>
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
A good way of doing this is to take the input as a string. Now find the length of the string as:
int length = str.length();
Make sure to include string and cctype. Now, run a loop that checks the whole string and sees if there is a character that is not a digit.
bool isInt = true;
for (int i = 0; i < length; i++) {
if(!isdigit(str[i]))
isInt = false;
}
If any character is not a digit, isInt will be false. Now, if your input(a string) is all digits, convert it back to an integer as:
int integerForm = stoi(str);
Store integerForm in your array.

Why is my C++ program only printing one character?

This program is suppose to generate passwords and compare to what the user inputed, if they match it breaks the while loop and outputs the user's input, but for some reason, the generated passwords are just one characters. I am new to C++, I just started like last Friday.
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
string Password, Passwords;
cout << "Enter a password: ";
getline(cin, Password);
sleep(.7);
system("clear");
while(Password.compare(Passwords)!= 0)
{
for (int x = 0; x <= Password.length(); x++)
{
for (char Alpha = 'a'; Alpha <= 'z'; Alpha++)
{
if(Alpha == 'z')
{
Alpha = 'a';
}
for(int I=0; I <= 10; I++)
{
Passwords = Alpha + I;
system("clear");
sleep(.7);
cout << Passwords <<endl;
}
}
}
}
cout << "Password found: " << Passwords <<endl;
return 0;
}
After a long back and forward in the comments, the OP explained what was his purpose. To generate random words of the same size as input and stop when it matched the input.
This code does what you want. It's in c++14 so you need a recent compiler and to set the c++14 option. Please note the actual use of random.
#include <iostream>
#include <string>
#include <random>
#include <algorithm>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
class RandomCharGenerator {
private:
static std::string s_chars_;
private:
std::random_device rd_{};
std::default_random_engine r_eng_{rd_()};
std::uniform_int_distribution<int> char_dist_{
0, static_cast<int>(s_chars_.size())};
public:
RandomCharGenerator() = default;
auto getRandomChar() -> char { return s_chars_[char_dist_(r_eng_)]; }
auto setRandomString(std::string &str) -> void {
std::generate(std::begin(str), std::end(str),
[this] { return this->getRandomChar(); });
}
};
std::string RandomCharGenerator::s_chars_ = "abcdefghijklmnopqrstuvwxyz";
auto main() -> int {
RandomCharGenerator rand_char;
auto input = std::string{};
cin >> input;
auto generated = std::string(input.size(), ' ');
do {
rand_char.setRandomString(generated);
cout << generated << endl;
} while (input != generated);
cout << "We generated what you input" << endl;
return 0;
}
For input longer than 4 characters it takes a long time to generate the input.
Ideone demo
To understand why you had only 1 char in your Passwords:
Passwords = Alpha + I;
Alpha is a char, I is an int. Their sum is an int. This is converted to char when assigning to Passwords which is a string. So Passwords is now a string composed of only one char.
It's not clear what that actual line of code was supposed to do, so can't tell you what would have been the fix. Maybe you meant to append to Passwords. Then you should have written Passwords += Alpha + I.
The code below is an example of what I am trying to make. I did not make the code below, am just giving you and example of what am trying to do in the code above
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
int main()
{
string password;
string Generated;
cout << "Password to find: ";
cin >> password;
char Alpha[]={'a'-1,'a','a','a','a','a','a','a','a','a'};
while( password.compare(Generated) != 0 )
{
Alpha[0]++;
for(int x=0;x<password.length();x++)
{
if (Alpha[x] == 'z'+1)
{
Alpha[x] = 'a';
Alpha[x + 1]++;
}
}
Generated=Alpha[password.length()-1];
for(int i=password.length()-2; i>=0 ; i-- )
Generated+= Alpha[i];
system("clear");
cout << "Trying: "<< Generated << endl;
}
system("clear");
sleep(1);
cout <<"Access Granted: "<< Generated << endl;
return 0;
}

Check if the input is a number or string in C++

I wrote the following code to check whether the input(answer3) is a number or string, if it is not a number it should return "Enter Numbers Only" but it returns the same even for numbers. Please suggest me a solution.
#include <iostream>
#include <string>
#include <typeinfo>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
using namespace std;
int main ()
{
string ques1= "Client's Name :";
string ques2 = "Client's Address :";
string ques3 = "Mobile Number :";
char answer1 [80];
string answer2;
int answer3;
cout<<ques1<<endl;
cin>>answer1;
cout<<ques2<<endl;
cin>>answer2;
cout<<ques3<<endl;
cin>>answer3;
if (isdigit(answer3))
{
cout<<"Correct"<<endl;
}
else
{
cout<<"Enter Numbers Only"<<endl;
}
system("pause>null");
return 0;
}
You can use regex to do this:
#include <regex>
bool isNumber(std::string x){
std::regex e ("^-?\\d+");
if (std::regex_match (x,e)) return true;
else return false;}
If you want to make isNumber() a generic function which can take any type of input:
#include <regex>
#include <sstream>
template<typename T>
bool isNumber(T x){
std::string s;
std::regex e ("^-?\\d+");
std::stringstream ss;
ss << x;
ss >>s;
if (std::regex_match (s,e)) return true;
else return false;}
The above isNumber() function checks for integer only, double or float value with precision (which contains dot .) will not return true.
If you want precision too, then change the regex line to:
std::regex e ("^-?\\d*\\.?\\d+");
If you want a more efficient solution, see this one.
If you're using C++98, you can use stringstreams (#include <sstream>):
std::string s = "1234798797";
std::istringstream iss(s);
int num = 0;
if (!(iss >> num).fail()) {
std::cout << num << std::endl;
}
else {
std::cerr << "There was a problem converting the string to an integer!" << std::endl;
}
If boost is available to you, you can use lexical_cast (#include <boost/lexical_cast.hpp>):
std::string s = "1234798797";
int num = boost::lexical_cast<int>(si);//num is 1234798797
std::cout << num << std::endl;
If C++11 is available to you, you can use the builtin std::stoi function from <string>:
std::string s = "1234798797";
int mynum = std::stoi(s);
std::cout << mynum << std::endl;
OUTPUTS:
1234798797
The function isdigit() is used to test for only digits ( 0,1,...,9)
use this function to check for numbers
bool is_number(const std::string& s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
The input to isdigit is an integer value. However, it will return true (non-zero) only if the value corresponds to '0'-'9'. If you convert them to integer values, they are 48-57. For all other values, isdigit will return false (zero).
You can check whether you got an integer by changing checking logic:
if ( cin.fail() )
{
cout<<"Correct"<<endl;
}
else
{
cout<<"Enter Numbers Only"<<endl;
}
Another answer using strtod:
bool isNumber(const std::string& s){
if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
char * p ;
strtod(s.c_str(), &p) ;
return (*p == 0) ;
}
To be able to handle any type of parameter use template:
#include <sstream>
template<typename T>
bool isNumber(T x){
std::string s;
std::stringstream ss;
ss << x;
ss >>s;
if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
char * p ;
strtod(s.c_str(), &p) ;
return (*p == 0) ;
}
Note:
White space will make it return false.
NAN and INF will make it return false (to be exact, any character except valid exponent will make it return false). If you want to allow nan and inf, delete the || std::isalpha(s[0]) part.
scientific form is allowed i.e 1e+12 will return true.
Double/float or integer will return true.
This is more efficient than the regex answer. (regex is heavy).
The interest phenomenon are the isdigit requires char to be cast to unsigned char. (Also see here).
This is a somewhat old question, but I figured I'd add my own solution that I'm using in my code.
Another way to check if a string is a number is the std::stod function, which has been mentioned, but I use it a bit differently. In my use case, I use a try-catch block to check if the input is a string or number, like so with your code:
...
try {
double n = stod(answer3);
//This will only be reached if the number was converted properly.
cout << "Correct" << endl;
} catch (invalid_argument &ex) {
cout << "Enter Numbers Only" << endl;
}
...
The primary problem with this solution is that strings that begin with numbers (but aren't all numbers) will be converted to numbers. This can be easily fixed by using std::to_string on the returned number and comparing it to the original string.

Determining input to be int or char in C++

I'm working on a small program for school to compute a factorial of an inputted number. I've got a good amount of experience in Java, but this is my first go at C++.
My problem: I need to be able to have a single input from the user, which is either an integer or the character 'q', which signifies the application needs to quit.
Here is my current attempt:
#include <stdio.h>
#include <iostream>
#include "Header.h"
using namespace std;
int x=0;
char y;
int main(int argc, char *argv[])
{
printf("Hello, please enter a number to compute a factorial (or 'q' to quit): ");
cin >> y;
x= (y-'0');
if(y=='q')
{ printf("Thanks for playing!\n");
exit(1);
}
long result= print_Factorial(x);
cout << x << "!= " << result << "\n";
return result;
}
This casting does not work, however. If I enter a double digit number, such as 12, it only converts to x the first digit of the two and computes that factorial. I'm sure this is simple, what am I missing?
Explicit answer or a lead to where I can learn more about this problem, anything is appreciated.
There are functions you can use to try and covert a string into a number, and which you can check if the conversion was a success or not. The std::strtol function is one of them:
std::string input;
std::cin >> input;
char* endptr = nullptr;
const char *input_ptr = input.c_str();
long value = std::strtol(input_ptr, &endptr, 10);
if (endptr == input_ptr)
{
// Input was not a valid number
}
else if (*endptr != '\0')
{
// Input starts with a valid number, but ends with some extra characters
// (for example "123abc")
// `value` is set to the numeric part of the string
}
else
{
// Input was a valid number
}
If you don't mind exceptions, then you can use e.g. std::stoi instead:
std::string input;
std::cin >> input;
int value = 0;
try
{
size_t endpos = 0;
value = std::stoi(input, &endpos);
if (endpos != input.length())
{
// Input starts with a valid number, but ends with some extra characters
// (for example "123abc")
// `value` is set to the numeric part of the string
}
else
{
// Input is a valid number
}
}
catch (std::invalid_argument&)
{
// Input not a valid number
}
catch (std::out_of_range&)
{
// Input is a valid number, but to big to fit in an `int`
}
The reason you're getting the first digit is because you're using
cin >> y; where y is a char, which holds one character. So you're only getting one character.
What you probably would want to do is get the answer as a string, and once you check that the string is not == "q", then you could convert it to an int.
#include <iostream>
#include <sstream>
int main() {
std::string in;
std::cout << "Please enter a digit: ";
while(std::cin >> in) {
std::cout << "Input: " << in << std::endl;
if(in.size() == 1) {
if(in[0] == 'q' || in[0] == 'Q') {
std::cout << "Quit" << std::endl;
return 0;
}
}
std::istringstream parse(in);
int value;
if(parse >> value) {
if(parse.eof()) {
std::cout << "Success" << std::endl;
return 0;
}
}
std::cout << "Please try again: ";
}
std::cerr << "This should not happen <control + d>" << std::endl;
return 1;
}
Your user can enter whatever line of text, you you have to read a "line of text" to validate.
#include <iostream>
#include <string>
#include <stdexcept>
int main()
{
std::string text;
std::getline(std::cin,text);
if(text.size()==1 && text[0]=='q')
{
std::cout << "quit command";
return 0;
}
try
{
int i = std::stoi(text); //may throw if text is not convertible
/* whatever elaboration and output */
return 0;
}
catch(const std::exception& e)
{
std::cout << "bad input: " << text << '\n';
std::cout << "caused excpetion: " << e.what() << std::endl;
}
return 3; //means "excpetion thorown"
}