I recently came across this SO question asking for methods to determine if a std::string
represents an integer. There is also this SO question for float
s. I decided to code up a few methods consolidating these questions.
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
namespace detail
{
const auto is_digit = [] (const char c) { return std::isdigit(c); };
}
bool is_integral(const std::string& str)
{
return !str.empty() && std::all_of(std::cbegin(str), std::cend(str), detail::is_digit);
}
bool is_floating_point(const std::string& str)
{
using std::cbegin; using std::cend;
auto it = std::find_if_not(cbegin(str), cend(str), detail::is_digit);
return it != cend(str) && *it++ == '.' && std::all_of(it, cend(str), detail::is_digit);
}
bool is_arithmetic(const std::string& str)
{
using std::cbegin; using std::cend;
if (str.empty()) return false;
auto it = std::find_if_not(cbegin(str), cend(str), detail::is_digit);
return it == cend(str) || (*it++ == '.' && std::all_of(it, cend(str), detail::is_digit));
}
Here's an example/expected behaviour:
#include <iostream>
int main()
{
std::string empty {};
std::string integer {"123"};
std::string floating1 {"123."};
std::string floating2 {"123.4"};
std::string neither1 {"123..4"};
std::string neither2 {"1r23"};
std::cout << std::boolalpha;
std::cout << is_integral(empty) << std::endl; // false
std::cout << is_floating_point(empty) << std::endl; // false
std::cout << is_arithmetic(empty) << std::endl; // false
std::cout << std::endl;
std::cout << is_integral(integer) << std::endl; // true
std::cout << is_floating_point(integer) << std::endl; // false
std::cout << is_arithmetic(integer) << std::endl; // true
std::cout << std::endl;
std::cout << is_integral(floating1) << std::endl; // false
std::cout << is_floating_point(floating1) << std::endl; // true
std::cout << is_arithmetic(floating1) << std::endl; // true
std::cout << std::endl;
std::cout << is_integral(floating2) << std::endl; // false
std::cout << is_floating_point(floating2) << std::endl; // true
std::cout << is_arithmetic(floating2) << std::endl; // true
std::cout << std::endl;
std::cout << is_integral(neither1) << std::endl; // false
std::cout << is_floating_point(neither1) << std::endl; // false
std::cout << is_arithmetic(neither1) << std::endl; // false
std::cout << std::endl;
std::cout << is_integral(neither2) << std::endl; // false
std::cout << is_floating_point(neither2) << std::endl; // false
std::cout << is_arithmetic(neither2) << std::endl; // false
std::cout << std::endl;
std::cout << is_integral(neither2) << std::endl; // false
std::cout << is_floating_point(neither2) << std::endl; // false
std::cout << is_arithmetic(neither2) << std::endl; // false
std::cout << std::endl;
return 0;
}
I'm looking for any improvements.
std::stoi()
,std::stod()
, etc. already are available for this functionality. \$\endgroup\$pos
parameter can be checked how many characters were actually processed. \$\endgroup\$