【问题标题】:How to validate that a number is int in C? [duplicate]如何验证一个数字在 C 中是 int 的? [复制]
【发布时间】:2020-03-19 20:09:28
【问题描述】:

如何验证我扫描的数字在 C 中是否为整数? 除了输入浮点数/双精度如 5.00/6.00 或 13.00 之外,我编写了一个适用于所有情况的代码。 我发现的几乎所有其他答案都忽略了这种情况。 到目前为止,我的解决方案是:

double tempValue;
printf("enter an integer:");
scanf("%lf",&tempValue);
int value= tempValue;
if(value==tempValue)
   printf("this is an int")
else printf("this isn't an integer");

感谢阅读。 更好地专注于帮助而不是投反对票。 (:

【问题讨论】:

  • “更好地专注于帮助而不是投反对票。” - 被投反对票的好方法。
  • 您的解决方案有什么问题?有用吗?

标签: c


【解决方案1】:

将其扫描成双精度,然后转换为 int 并检查是否有截断:

double x = <your number>;
int y = (int) x;

if (x-y)
{
    // your number is NOT an integer
}
else
{
   // your number is an integer
}

【讨论】:

  • @nivpeled 如果您在回答中提供了一些解释,那就更好了。
  • 起初它认为它有效,但猜测它没有。仍然面临同样的问题。假设 x= 5.00;输出是 x 是一个整数。
  • 但是 5.00 是一个整数
  • 它可以用整数表示,但它有小数位,所以我猜 OP 认为它有一个浮点数。在 C 中,5.00 是双字面值(而 5.00f 是浮点数,5 是整数)。
  • 争论 5.00 是否是整数是没有意义的。该问题明确抱怨当前代码未能拒绝“5.00”。所以我们知道 OP 想要拒绝带小数点的数字,尽管它们有术语。他们在要求“整数”而不是描述他们想要接受或拒绝的字符模式的问题中犯了一个错误。所以问题不在于区分代表整数或不代表整数的数字,而是区分不包含小数点的数字。争论什么数字在数学上是整数是无关紧要的。
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i, n, ch, done;

    n = scanf("%d", &i);
    if (n == 1) {
        ch = getchar();
        done = ch != '.';
        ungetc(ch, stdin);
    } else {
        done = 0;
    }
    if (done) {
        puts("this is an int");
    } else {
        puts("this is not an int");
    }
    return 0;
}

【讨论】:

  • 没有解释的代码不是如何做某事的好答案,也不是很丰富。
  • 下一个字符是 ',' 是什么? (是的,我是法国人,我们使用逗号而不是点作为小数分隔符,抱歉 XD)
  • @Bktero 我们在瑞典也这样做。但是,C 中的输入函数始终使用句点作为逗号分隔符。
  • scanf 可以通过将语言环境设置为非 C 语言环境来接受逗号作为小数点。
  • 让我们更笼统地说:如果下一个字符不是数字也不是点怎么办。如果输入“123A”会怎样?
【解决方案3】:

为了区分5.005,需要对字符串进行处理。
使用scanf 转换为双精度会丢失此信息。

例如:

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

int main(void) {
        char  buffer[256];
        printf("enter an integer:");
        scanf("%255s",buffer);

        char  valueStr[256];
        sprintf(valueStr,"%d", atoi(buffer));
        if(strcmp(valueStr,buffer)==0)
                printf("'%s' is an integer\n",buffer);
        else
                printf("'%s' isn't an integer\n", buffer);

        return 0;
}

Live Test

这会将输入读取为字符串,将其转换为int,将 int 转换为字符串并与输入字符串进行比较。

【讨论】:

  • atoi() 不应使用,尤其是在转换可能失败的情况下!使用 strtol() 代替
  • @Bktero 如果转换失败valueStr 将是0 与转换后的字符串不同,那么应该可以吗?
  • 参考手册页:linux.die.net/man/3/atoi:“atoi() 函数将 nptr 指向的字符串的初始部分转换为 int。行为与 strtol(nptr, NULL, 10 ); 除了 atoi() 不检测错误。"使用 strtol() 您不必 sprintf() 然后 strcmp() 字符串。例如,请参阅我的答案:)
  • @Bktero:你是对的,但是在atoi错误转换的情况下输入不是整数。
  • 请记住,当您要求输入数字时,人类可以输入任何内容,甚至是字母;-)
【解决方案4】:

scanf() 用于格式化输入(这就是为什么它的名称中有一个 f ^^)。在这里,您的输入未格式化,因此您必须执行其他操作。

最好的方法是使用fgets() 获取用户输入,然后检查内容。如前所述,strtol() 是此任务的专用函数:您尝试将字符串转换为数字,然后查看转换是否成功...。

这是一个例子:

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

#define SIZE    1024

void convert() {

    // Get user input
    char buffer[SIZE] = {0};
    printf("Enter number: ");
    char* result = fgets(buffer, SIZE, stdin);
    assert(result != NULL);

    printf("User input = %s\n", buffer);    

    // Convert
    char* end = NULL;
    long int value = strtol(buffer, &end, 10);

    if (buffer[0] == '\n') {
        // The user didn't input anything
        // and just hit 'enter' kit
        puts("Nothing to convert");
    }    
    else if(*end == '\n') {
        // Assuming that 'buffer' was big enough to get all characters,
        // then the last character in 'buffer' is '\n'.
        // Because we want all characters except '\n' to be converted
        // we have to check that 'strtol()' has reached this character.
        printf("Conversion with success: %ld\n", value);
    } else {
        printf("Conversion failed. First invalid character: %c\n", *end);
    }
}

int main() {
  while(1) convert();
}

如果你真的想要int 而不是long int,那么你就得花点小心思了。我的第一个想法是做这样的事情:

// Fits in integer?
int valueInt = value;
// some bits will be lost if 'value' doesn't fit in an integer
// hence the value will be lost

if (valueInt == value) {
  printf("Great: %ld == %d\n", value, valueInt);
} else {
  printf("Sorry: %ld != %d\n", value, valueInt);
}

【讨论】:

    【解决方案5】:

    考虑到您永远无法确定任意数字是整数(除非您检查输入并将其视为字符串)。

    最好的近似值是检查与假定整数值相比的值是否低于machine epsilon

    bool doubleMaybeInteger(double input) {
        return ((input - floor(input)) < DBL_EPSILON)
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 2014-01-21
      • 2020-04-10
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2020-06-07
      相关资源
      最近更新 更多