I'm working on a project in c++ (which I just started learning) and can't understand why this function is not working. I'm attempting to write a "Person" class with a variable first_name, and use a function set_first_name to set the name. Set_first_name needs to call a function(the one below) to check if the name has any numbers in it. The function always returns false, and I'm wondering why? Also, is this the best way to check for numbers, or is there a better way?
bool Person::contains_number(std::string c){ // checks if a string contains a number
if (c.find('0') == std::string::npos || c.find('1') == std::string::npos || c.find('2') == std::string::npos || c.find('3') == std::string::npos
|| c.find('4') == std::string::npos || c.find('5') == std::string::npos || c.find('6') == std::string::npos || c.find('7') == std::string::npos
|| c.find('8') == std::string::npos || c.find('9') == std::string::npos){// checks if it contains number
return false;
}
return true;
}
It always returns false because your logic is backwards. You are using the || operator with == npos checks. If any one particular digit is missing from the string, == npos evaluates to true and || is satisfied, so you return false. You need to using != npos checks and then return true if any check evaluates to true:
bool Person::contains_number(const std::string &c)
{
if (c.find('0') != std::string::npos ||
c.find('1') != std::string::npos ||
c.find('2') != std::string::npos ||
c.find('3') != std::string::npos ||
c.find('4') != std::string::npos ||
c.find('5') != std::string::npos ||
c.find('6') != std::string::npos ||
c.find('7') != std::string::npos ||
c.find('8') != std::string::npos ||
c.find('9') != std::string::npos)
{
return true;
}
return false;
}
Or:
bool Person::contains_number(const std::string &c)
{
return (
c.find('0') != std::string::npos ||
c.find('1') != std::string::npos ||
c.find('2') != std::string::npos ||
c.find('3') != std::string::npos ||
c.find('4') != std::string::npos ||
c.find('5') != std::string::npos ||
c.find('6') != std::string::npos ||
c.find('7') != std::string::npos ||
c.find('8') != std::string::npos ||
c.find('9') != std::string::npos
);
}
A simplier solution is to use find_first_of() instead of find():
bool Person::contains_number(const std::string &c)
{
return (c.find_first_of("0123456789") != std::string::npos);
}
Change all your || to &&.
Better yet:
return std::find_if(s.begin(), s.end(), ::isdigit) != s.end();
Or, if you have it:
return std::any_of(s.begin(), s.end(), ::isdigit);
C++11:
#include <algorithm>
#include <cctype>
#include <string>
#include <iostream>
bool has_any_digits(const std::string& s)
{
return std::any_of(s.begin(), s.end(), ::isdigit);
}
int main()
{
std::string query("H311o, W0r1d!");
std::cout << query << ": has digits: "
<< std::boolalpha
<< has_any_digits(query)
<< std::endl;
return 1;
}
Output:
H311o, W0r1d!: has digits: true
How to test if a string contains any digits in C++
This should do it!
if (std::string::npos != s.find_first_of("0123456789"))
{
std::cout << "digit(s)found!" << std::endl;
}
You are using || (or operator) to check several conditions in an if statement.
The or operator returns true (satisfies the condition) if one of the expression is true.
The or operator evaluates first the expression on its left: if that is true then it doesn't evaluate the expression on its right and returns true. If the expression on the left is false then the expression on the right is evaluated and the result of it is returned as result of || operator
This is what happen in your function:
- does c contains '0' ? if no (because std::string::npos in find() means not found) then return false
- does c contains '1' ? if no then return false
- ...
So, replace the or operators with && (and operator).
来源:https://stackoverflow.com/questions/9642292/function-to-check-if-string-contains-a-number