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.
Related
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;
}
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.
How can I get tis to work by passing a string to a Boolean function? I need to have the user input a series of strings, and after each entry, the program should give feedback depending upon whether or not the string fit the given criteria. The string should contain the substring of "1101", without any letters. Thanks for all your help
#include <iostream>
#include <cstring> // for strstr
#include <string>
#include <cctype>
using namespace std;
bool stringCompare(char*y);
string str2;
int main ()
{
string str1, str2;
str1= "1101";
do
{
cout << "Please enter your string: " << endl;
cin >> str2;
while((stringCompare(str2)) == true)
{
if(strstr(str2.c_str(),str1.c_str())) // Primary string search function
{
cout << "ACCEPTED " << endl;
}
else
cout << "NOT ACCEPTED " << endl;
}
} while (2 > 1);
return 0;
}
bool stringCompare(char*y)
{
for(int a = 0; a < strlen(str2); a++)
{
if (!isdigit(str2[a]))
return false;
}
return true;
}
stringCompare takes a parameter of type char*, but you're trying to pass a std::string. That won't work.
You can either use the c_str method of std::string, to get a const char* pointing to the std::string's internal char array. This means that you'll have to chance the parameter to const char*.
Or, much better, you can replace stringCompare to take a reference to a std::string:
bool stringCompare(string& y)
and change strlen(str2) to str2.length(). (Or even better, replace the whole loop to simply:
for(char& ch : str2) // range-based for-loop loops over the entire str2
{
if (!isdigit(ch))
return false;
}
)
Also, you don't need to compare the return value == true. Just do:
while(stringCompare(str2))
I'm writing a very simple program where I want to get user input from the standard input stream (keyboard) and then do something based on what input I encountered. However, the problem is that sometimes the input will be a number (double) while othertimes it'll be a string. I'm not sure exactly what methods calls I need in order to parse it properly (perhaps something similar to Integer.parseInt in java).
Here is some pseduocode of what I would like to do:
cin >> input
if(input is equal to "p") call methodA;
else if(input is a number) call methodB;
else call methodC;
I think this is what you need:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void a(string& s){ cout << "A " << s << endl; }
void b(double d){ cout << "B " << d << endl; }
void c(string& s){ cout << "C " << s << endl; }
int main()
{
std::string input;
cin >> input;
if (input == "p")
a(input);
else
{
istringstream is;
is.str(input);
double d = 0;
is >> d;
if (d != 0)
b(d);
else
c(input);
}
return 0;
}
Hope this helps ;)
std::string input;
std::cin >> input;
if(input =="p") f();
else if(is_number(input)) g();
else h();
Now implement is_number() function:
bool is_number(std::string const & s)
{
//if all the characters in s, are digits, then return true;
//else if all the characters, except one, in s are digits, and there is exactly one dot, then return true;
//else return false
}
Implement this function yourself, as it seems to be homework. You can also consider case like the number may begin with sign + or -.
The usual solution I use is to read the input as a line (using
std::getline rather than >>), and parse it as I would in any
language—boost::regex is very useful here; if you are sure that
you can count on C++11, it's std::regex (which I think is almost
identical to Boost). So you end up with something like:
std::string line;
if ( ! std::getline( std::cin, line ) ) {
// Error reading line (maybe EOF).
} else {
if ( regex_match( line, firstFormat) ) {
processFirstFormat( line );
} else if ( regex_match( line, secondFormat) ) {
processSecondFormat( line ) ;
} ...
}
Apparently this is suposed to work in showing if a string is numerical, for example "12.5" == yes, "abc" == no. However I get a no reguardless of the input.
std::stringstream ss("2");
double d; ss >> d;
if(ss.good()) {std::cout<<"number"<<std::endl;}
else {std::cout<<"other"<<std::endl;}
Don't use good()! Test if the stream is failed or not:
if (ss)
Good tells you if any of eofbit, badbit, or failbit are set, while fail() tells you about badbit and failbit. You almost never care about eofbit unless you already know the stream is failed, so you almost never want to use good.
Note that testing the stream directly, as above, is exactly equivalent to:
if (!ss.fail())
Conversely, !ss is equivalent to ss.fail().
Combining the extraction into the conditional expression:
if (ss >> d) {/*...*/}
Is exactly equivalent to:
ss >> d;
if (ss) {/*...*/}
However, you probably want to test if the complete string can be converted to a double, which is a bit more involved. Use boost::lexical_cast which already handles all of the cases.
If you want to check whether a string contains only a number and nothing else (except whitespace), use this:
#include <sstream>
bool is_numeric (const std::string& str) {
std::istringstream ss(str);
double dbl;
ss >> dbl; // try to read the number
ss >> std::ws; // eat whitespace after number
if (!ss.fail() && ss.eof()) {
return true; // is-a-number
} else {
return false; // not-a-number
}
}
The ss >> std::ws is important for accepting numbers with trailing whitespace such as "24 ".
The ss.eof() check is important for rejecting strings like "24 abc". It ensures that we reached the end of the string after reading the number (and whitespace).
Test harness:
#include <iostream>
#include <iomanip>
int main()
{
std::string tests[8] = {
"", "XYZ", "a26", "3.3a", "42 a", "764", " 132.0", "930 "
};
std::string is_a[2] = { "not a number", "is a number" };
for (size_t i = 0; i < sizeof(tests)/sizeof(std::string); ++i) {
std::cout << std::setw(8) << "'" + tests[i] + "'" << ": ";
std::cout << is_a [is_numeric (tests[i])] << std::endl;
}
}
Output:
'': not a number
'XYZ': not a number
'a26': not a number
'3.3a': not a number
'42 a': not a number
'764': is a number
' 132.0': is a number
'930 ': is a number
You should use an istringstream so that it knows it's trying to parse input. Also, just check the result of the extraction directly rather than using good later.
#include <sstream>
#include <iostream>
int main()
{
std::istringstream ss("2");
double d = 0.0;
if(ss >> d) {std::cout<<"number"<<std::endl;}
else {std::cout<<"other"<<std::endl;}
}
int str2int (const string &str) {
stringstream ss(str);
int num;
if((ss >> num).fail())
{
//ERROR: not a number
}
return num;
}