【问题标题】:Determine if a C string is a valid int in C确定 C 字符串是否是 C 中的有效 int
【发布时间】:2012-04-02 22:41:12
【问题描述】:

我需要检查一个 C 字符串是否是一个有效的整数。

我都试过了

int num=atoi(str);

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

但是在这两行中发送字符串"8 -9 10",只返回8,并没有说明这个字符串无效。

谁能提出替代方案?

【问题讨论】:

  • atoi 不进行错误检查;如果str 不包含int 值的表示,它的行为是未定义的。 (典型实现返回0。)sscanf 更好,但如果字符串中的值不能表示为int,则其行为未定义。此外,您的标题说您要检查有效的 int,但您的问题正文显示“有效整数”;他们不是一回事。 int 是几个 integer 类型之一。

标签: c string validation int


【解决方案1】:

看看strtol(),它可以通过指针返回告诉你字符串的无效部分。

并提防热情的示例代码。请参阅手册页以了解全面的错误处理。

【讨论】:

  • strtol() 只是将指针设置为字符串中的下一个“对象”。它不验证任何东西。
  • @g24l 如果该指针最终指向 NULL,那么您就知道整个字符串是有效的。如果不是,则不是。多多!
  • 如果它是一个空终止的字符串。
  • 好吧,你说得对,我刚刚注意到她指定了 C 字符串。
  • 请注意,strtol() 返回一个long 结果。如果要检查有效的int,还需要检查结果是否在INT_MIN .. INT_MAX 范围内。
【解决方案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;
}

[注意:否则我可能会使用 isdigit(*str++) 而不是 else 以使其更短,但我记得标准说 isdigit 可能是一个宏。]

我想一个限制是,如果字符串中的数字不适合整数,这不会返回 false。这对你来说可能很重要,也可能无关紧要。

【讨论】:

  • “没那么难”,但你必须回来改变它;)
  • @blueshift 点了,但是在 5 分钟内将代码输入 Web 表单时进行 1 次编辑对我来说并没有那么糟糕。 :-)
  • 在这种情况下,我不知道自己滚动或尝试正确处理 strtol() 是否更容易出错。我可能仍会推荐 strtol。
  • 不,你不会被激怒,我支持你,但我认为 strtol 更安全。
  • @asveikau:所以,这会接受'-37',但会拒绝'+42'
【解决方案3】:

稳健地执行此操作的一种简单方法是读取 int 并确保其字符串表示形式与输入字符串相同,例如结合 atoiitoa

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

【讨论】:

  • 好主意:)。但是,这也需要修剪前导和尾随空格,以使其正常工作。
  • 请注意,此解决方案不符合 ANSI。
  • 不错的解决方案!之后要小心释放。
【解决方案4】:

要检查字符串是否包含有效数字,您可以使用正则表达式。例如对于整数使用:

[-+]?[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";

【讨论】:

    【解决方案5】:

    抱歉挖掘了这个话题,但为了完整起见,因为这个线程是谷歌搜索时的第一个匹配......

    可以使用类似的东西:

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

    %n 指令,根据手册页似乎是标准 C,计算处理的字符数。

    [编辑] sscanf 似乎没有提供检测溢出的方法,因此恕我直言,应该首选 strtoX 函数系列。

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 1970-01-01
      • 2011-03-05
      • 2011-02-14
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多