【问题标题】:C - Check that an int read by scanf is in the range of the integersC - 检查 scanf 读取的 int 是否在整数范围内
【发布时间】:2012-02-24 22:27:00
【问题描述】:

我有这段代码,它使用 scanf 读取一个整数,并通过查看缓冲区来检查它是否真的是一个整数。

int e_1; 
char c[1];
// noNeedToCleanBuffer is used to avoid buffer cleaning the first time.
int noNeedToCleanBuffer = 1;
do {
    // Clears the buffer.
    if (!noNeedToCleanBuffer)
        while ((c[0] = getchar()) != '\n') ;

    noNeedToCleanBuffer = 0;
    printf("Input an integer value: \n");
    e_1 = scanf("%d", &n);  

    c[0] = getchar();
} while ((e_1 != 1 && c[0] != 10) || (e_1 == 1 && c[0] != 10));

但是我不知道如何检查输入是否在 INT_MIN 和 INT_MAX 之间(我从 limits.h 中得到这些)。

我正在考虑将数字作为字符串并将其与表示 INT_MIN 和 INT_MAX 的两个字符串进行比较,但是由于我使用的是标准 c99,因此不允许使用 atoi() 或 itoa()。

【问题讨论】:

  • 您可以使用 strtol() 等,在 C99 中..
  • mkssoftware.com/docs/man3/strtol.3.asp 这会将其转换为 long int 而不是 int。还是谢谢
  • long 有什么问题?然后您可以轻松地检查longINT_MININT_MAX,因为longs 总是大于(或等于)ints,您可以使用strtol() 进行错误处理以防万一甚至不适合long 的东西。另外,请注意 atoi()(但不是 itoa()在 C99 中,但它不进行错误检查。
  • long 大于 int 取决于我运行程序的机器。所以我不能依赖它。
  • 不,long 大于或等于 intall 符合实现。 2 <= sizeof(int) <= 4 <= sizeof(long)。这是由标准保证的(实际上,IIRC 标准以位而不是字节指定它,但这与本次讨论无关)。所以你可以便携地使用这种方法。

标签: c int range


【解决方案1】:

如果你真的只是想检查存储它-

1.)长期存储,然后检查

2.)将数字存储在字符串中,然后通过获取每个数字并将其存储在字符串中,然后使用 strcmp() 将 INT_MAX 转换为字符串

num = INT_MAX;
i = 0;

while(num != 0){
    str[i] = num % 10;
    num = num / 10;
    i++;
}

这个字符串中的数字是相反的,你可以通过一个简单的循环很容易地把它反转

然后使用strcmp();

【讨论】:

  • 1.除了在某些机器中之外,long 没有比 int 更广泛的可接受输入范围。 2.这可以工作,但我想知道是否有一个函数可以进行转换并且允许在c99下使用它
  • @sic2 我真的看不出字符串方法有什么问题
  • 我只是认为这可能很昂贵,但我才意识到时间复杂度是 O(log(n))
  • 点击答案左侧的复选按钮接受答案。
【解决方案2】:

使用s 转换说明符和scanf 读取字符串并使用strtol 函数检查数字。

  • strtol 让您首先检查数字的格式是否正确(整数)以及它是否可以表示为 long 整数
  • 然后检查long 数字是否在INT_MININT_MAX 之间。

【讨论】:

  • 先生,如果我有一个 unsigned int 并且我使用 scanf 尝试存储超过它的范围,会发生什么?
【解决方案3】:

任何给定数据类型(包括int)的变量的值将始终在该数据类型的范围内。这是由编译应用程序的平台定义和执行的。

如果您只是想通过“证明”变量在您的类型范围内的练习,您必须将其转换为可以容纳更大范围值的类型的变量。例如:

int foo = /* some value to test */;
long bar = (long)foo;

if ( (bar < (long)INT_MIN) || (bar > (long)INT_MAX) ) return false;

【讨论】:

    猜你喜欢
    • 2011-06-29
    • 2011-03-31
    • 2011-09-21
    • 2015-11-28
    • 2014-04-08
    • 2011-08-28
    • 1970-01-01
    • 2023-04-03
    • 2017-07-13
    相关资源
    最近更新 更多