Определите, является ли строка C допустимым int в C - PullRequest
19 голосов
/ 18 марта 2012

Мне нужно проверить, является ли строка C допустимым целым числом.

Я пробовал оба

int num=atoi(str);

и

int res=sscanf(str, "%d", &num);

Но отправка строки "8 -9 10" в обе строки вернула просто 8, без указания недействительности этой строки.

Может кто-нибудь предложить альтернативу?

Ответы [ 5 ]

30 голосов
/ 18 марта 2012

Посмотрите на strtol (), он может сообщить вам о недопустимых частях строки путем возврата указателя.

И остерегайтесь восторженного примера кода ... см. Справочную страницу для полной обработки ошибок.

7 голосов
/ 18 марта 2012

Может быть, я воспламенен за то, что я не использую strtol или подобные libc функции, но рассуждать об этой проблеме не так уж и сложно:

#include <stdbool.h>  // if using C99...  for C++ leave this out.
#include <ctype.h>

bool is_valid_int(const char *str)
{
   // Handle negative numbers.
   //
   if (*str == '-')
      ++str;

   // Handle empty string or just "-".
   //
   if (!*str)
      return false;

   // Check for non-digit chars in the rest of the stirng.
   //
   while (*str)
   {
      if (!isdigit(*str))
         return false;
      else
         ++str;
   }

   return true;
}

[NB: в противном случае я мог бы сделать isdigit(*str++) вместо else, чтобы сделать его короче, но я помню, что стандарты говорят, что возможно, что isdigit - это макрос.]

Я предполагаю, что одно ограничение заключается в том, что это не возвращает false, если число в строке не помещается в целое число. Это может иметь или не иметь значения для вас.

2 голосов
/ 20 марта 2012

Простой способ сделать это надежно - прочитать int и убедиться, что его строковое представление идентично входной строке, например, объединяя atoi и itoa:

int is_int(char const* p)
{
    return strcmp(itoa(atoi(p)), p) == 0;
}
0 голосов
/ 19 сентября 2017

Извините за то, что выкопал тему, но ради полноты и потому что эта тема - первое совпадение при поиске в Google ...

Можно использовать что-то вроде:

ret = sscanf(string, "%d%n", &number, &idx);
if (ret == 0 || string[idx] != '\0')
    /* handle the error */

директива %n, которая в соответствии с man-страницей является стандартной C, считает количество обработанных символов.

[Редактировать] Похоже, что sscanf не позволяет обнаруживать переполнения, поэтому семейство функций strtoX должно быть предпочтительным, IMHO.

0 голосов
/ 14 мая 2016

Для проверки, содержит ли строка допустимое число, вы можете использовать регулярное выражение.Например, для целых чисел используйте:

[- +]? [0-9] +

и общий случай для чисел с плавающей запятой:

[+ -]? [0-9] + [.]? [0-9] * ([eE] [- +]? [0-9] +)?

В случае C ++ 11 функций регулярных выраженийдоступно в библиотеке, например, "std :: regex_match (.....)" дает точное совпадение.Код должен выглядеть так:

#include <regex>
.....
std::string strnumber("-1.234e+01");
float number;
if(regex_match(strnumber,std::regex("[+-]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?"))
number=std::stof(strnumber);
else
std::cout<<"error, string is not a valid number";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...