【问题标题】:atoi() accepting strings mixed with numberatoi() 接受与数字混合的字符串
【发布时间】:2022-11-19 02:35:08
【问题描述】:

对于一项任务,我需要使用 if atoi(INPUT) == 0 来检查用户输入是否为有效整数而不是 0。问题是当我输入任何以整数开头的字符串时,它会自动被接受,即使有非整数字符在整数之后,例如“1aaaabcc”被接受。

我知道 atoi() 在我刚才说的例子中,会取 1 并忽略它,但理论上这应该是用户的错误输入,因为它不是有效整数。是否可以将某些内容添加到我的代码中(不添加任何库)或使用 atoi 进行更改以解决此问题?

如果您需要示例代码以防不清楚,请告诉我。

【问题讨论】:

  • 无论如何你不应该使用atoi。使用strtol,它可以告诉你它在哪里停止解析。
  • atoi 的问题在于它没有提供简单的错误处理方法。如果你使用strtol,你可以使用结束指针来检查整个字符串是否被消耗。您还可以在调用 atoi 之前验证必须验证的字符串是否全部为数字。

标签: c c-strings atoi strtol


【解决方案1】:

函数atoi是这个函数调用的“别名”

atoi: (int)strtol(nptr, (char **)NULL, 10)

因此,在您的情况下,您应该使用函数 strtol 并传递不等于指向指针的 NULL 的第二个参数。在这种情况下,您可以检查指针是否指向相应字符串的末尾。

这是一个演示程序

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    char *endptr;

    int n = ( int )strtol( "A", &endptr, 10 );

    printf( "n = %d, *endptr = %d
", n, *endptr );

    n = ( int )strtol( "10A", &endptr, 10 );

    printf( "n = %d, *endptr = %d
", n, *endptr );

    n = ( int )strtol( "10", &endptr, 10 );

    printf( "n = %d, *endptr = %d
", n, *endptr );
}

它的输出是

n = 0, *endptr = 65
n = 10, *endptr = 65
n = 10, *endptr = 0

正如您仅在函数 strtol 的第三次调用中看到的那样,指针 endptr 指向终止零字符 '

【解决方案2】:

aoti() 对于快速和肮脏的代码很有用,但不能胜任强大的错误处理任务。

整数后的非整数字符,如 "1aaaabcc" 最好用 strtol() 检测。

使用strtol(),我们可以检测到更多。

  1. int 超出范围,例如 "12345678901234567890",但长度不一样 "00000000000000000001"

  2. 当文本全部为空白时,允许在整数后使用非整数字符。这是合理的,因为 strtol()/atoi() 接受可选的前导空格。它还允许传递整个线输入像"1234 "

  3. 没有转换,如"asd"" """

    我推荐一个辅助函数

    // Return true on success    
    bool convert_string_to_int(int *dest, const char *s) {
      errno = 0;
      char *endptr;  // Gets updated to point to the end of the conversion.
      long lvlaue = strtol(s, &endptr, 0);
      if (s == endptr) {
        *dest = 0;
        return false;  // No conversion
      }
      if (errno == ERANGE || lvalue < INT_MIN || lvalue > INT_MAX) {
        errno = ERANGE;
        *dest = lvalue < 0 ? INT_MIN : INT_MAX; 
        return false;  // Out of range.
      }
      *dest = (int) lvalue;
      while (isspace(*((unsigned char *)endptr))) {
        endptr++;
      }
      if (*endptr) {
        return false;  // Junk at the end.
      }
      if (errno) {
        return false;  // Implementation specific errors like s == NULL
      }
      return true;
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2016-12-06
    相关资源
    最近更新 更多