Как определить, является ли строка числом с C ++? - PullRequest
106 голосов
/ 11 января 2011

У меня было немало проблем при попытке написать функцию, которая проверяет, является ли строка числом.Для игры, которую я пишу, мне просто нужно проверить, является ли строка из файла, который я читаю, числом или нет (я буду знать, является ли это параметром таким образом).Я написал нижеприведенную функцию, которая, по моему мнению, работала гладко (или я случайно отредактировал ее, чтобы остановить, или я шизофреник, или Windows шизофреник):

bool isParam (string line)
{
    if (isdigit(atoi(line.c_str())))
        return true;

    return false;
}

Ответы [ 30 ]

5 голосов
/ 15 мая 2013

Вот решение для проверки положительных целых чисел:

bool isPositiveInteger(const std::string& s)
{
    return !s.empty() && 
           (std::count_if(s.begin(), s.end(), std::isdigit) == s.size());
}
3 голосов
/ 30 марта 2014

Брендан это

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}

почти нормально.

при условии, что любая строка, начинающаяся с 0, является числом, Просто добавьте чек на этот случай

bool isNumber(const string &line) 
{
 if (line[0] == '0') return true;
 return (atoi(line.c_str()));
}

ofc "123hello" вернет true, как заметил Тони Д.

2 голосов
/ 14 июля 2016

Самое простое, что я могу придумать в c ++

bool isNumber(string s) {
    if(s.size()==0) return false;
    for(int i=0;i<s.size();i++) {
        if((s[i]>='0' && s[i]<='9')==false) {
            return false;
        }
    }
    return true;
}

Пример рабочего кода: https://ideone.com/nRX51Y

2 голосов
/ 30 ноября 2017

Использование <regex>. Этот код был протестирован!

bool isNumber(const std::string &token)
{
    return std::regex_match(token, std::regex("(\\+|-)?[0-9]*(\\.?([0-9]+))$"));
}
2 голосов
/ 25 июля 2014

Решение на основе комментария от kbjorklu :

bool isNumber(const std::string& s)
{
   return !s.empty() && s.find_first_not_of("-.0123456789") == std::string::npos;
}

Как и в случае ответа Дэвида Ректора , он не надежен для строк с несколькими точками или знаками минус, но вы можете удалить эти символы, чтобы просто проверить на целые числа.


Однако я неравнодушен к решению, основанному на решении Бена Фойгта , использующем strtod в cstdlib для просмотра десятичных значений, научной / инженерной записи, шестнадцатеричной записи (C ++ 11) или четный INF / INFINITY / NAN (C ++ 11):

bool isNumberC(const std::string& s)
{
    char* p;
    strtod(s.c_str(), &p);
    return *p == 0;
}
1 голос
/ 22 ноября 2015
bool isNumeric(string s){
    if ( !s.empty() && s[0] != '-' )
        s = "0" + s; //prepend 0

    string garbage;

    stringstream ss(s); 
    ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
    //if there is no garbage return true or else return false
    return garbage.empty(); 
}

как это работает: перегрузка stringstream >> может преобразовывать строки в различные арифметические типы, которые он делает, последовательно считывая символы из потока строк (в данном случае ss), пока в нем не заканчиваются символыИЛИ следующий символ не соответствует критериям для сохранения в тип переменной назначения.

example1:

stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11

example2:

stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11

example3:

stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)

объяснение переменной «мусора»:

почему бы просто не проверить, есть ли у извлечения в моем double правильное значение, а затем вернуть true, если оно есть?

Обратите внимание, пример 3 выше все равно будет успешно считывать число 11 в переменную my_number, даже если входная строка - "11ABCD" (которая не является числом).

для обработки этогоВ этом случае мы можем выполнить другое извлечение в строковую переменную (которую я назвал мусором), которая может прочитать все, что могло остаться в строковом буфере после первоначального извлечения в переменную.типа двойной.Если что-то осталось, оно будет считано «мусором», что означает, что переданная полная строка не была числом (она просто начинается с единицы).в этом случае мы бы хотели вернуть false;

объяснение с добавлением "0":

попытка извлечь один символ в двойку не удастся (возвращая 0 в наш double), но все равно будет перемещать позицию строкового буфера после символа. В этом случае наше чтение мусора будет пустым, что приведет к неправильному возвращению функции true. Чтобы обойти это, я добавил к строке 0, так чточто, например, если переданная строка была "a", она заменяется на "0a", так что 0 будет извлечен в двойное число, а "a" извлечено в мусор.

добавление 0 не повлияетзначение числа, так что число все равно будет правильно извлечено в нашу двойную переменную.

1 голос
/ 19 ноября 2015
include <string>

Для проверки двойников:

bool validateDouble(const std::string & input) {
int decimals = std::count(input.begin(), input.end(), '.'); // The number of decimals in the string
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == decimals + negativeSigns) // Consists of only decimals and negatives or is empty
    return false;
else if (1 < decimals || 1 < negativeSigns) // More than 1 decimal or negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-.0123456789") != input.size()) // The string contains a character that isn't in "-.0123456789"
    return false;
return true;

}

Для проверки значений (с отрицательными значениями)

bool validateInt(const std::string & input) {
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == negativeSigns) // Consists of only negatives or is empty
    return false;
else if (1 < negativeSigns) // More than 1 negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-0123456789") != input.size()) // The string contains a character that isn't in "-0123456789"
    return false;
return true;

}

Для проверки неподписанных целых чисел

bool validateUnsignedInt(const std::string & input) {
return (input.size() != 0 && strspn(input.c_str(), "0123456789") == input.size()); // The string is not empty and contains characters only in "0123456789"

}

1 голос
/ 11 января 2011

После более подробного изучения документации я нашел ответ, который отвечает моим потребностям, но, вероятно, не будет таким полезным для других.Вот оно (без надоедливого возврата истинных и ложных утверждений :-))

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}
1 голос
/ 06 апреля 2015

Я думаю, что это регулярное выражение должно обрабатывать почти все случаи

"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"

, чтобы вы могли попробовать следующую функцию, которая может работать как с Unicode, так и с ANSI

bool IsNumber(CString Cs){
Cs.Trim();

#ifdef _UNICODE
std::wstring sr = (LPCWSTR)Cs.GetBuffer(Cs.GetLength());
return std::regex_match(sr, std::wregex(_T("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?")));

#else
    std::string s = (LPCSTR)Cs.GetBuffer();
return std::regex_match(s, std::regex("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"));
#endif
}
1 голос
/ 02 августа 2015

, чтобы проверить, является ли строка целым числом или числом с плавающей запятой или что вы можете использовать:

 #include <sstream>

    bool isNumber(string str) {
    double d;
    istringstream is(str);
    is >> d;
    return !is.fail() && is.eof();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...