Подтвердить что ты не робот

Определите, является ли строка C допустимым int в C

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

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

int num=atoi(str);

и

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Может быть, я получу пламя за то, что не использовал 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, если число в строке не будет вписываться в целое число. Это может или не важно для вас.

Ответ 3

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

int is_int(char const* p)
{
    return strcmp(itoa(atoi(p)), p) == 0;
}

Ответ 4

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

? [- +] [0-9] +

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

[+ -] [0-9] + [0-9] * ([еЕ]? [- +], [0-9] +)? [.]?

В случае С++ 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";

Ответ 5

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

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

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

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

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