【问题标题】:Is there a way how to check if input I have scanfed is a number? With IF function in C?有没有办法检查我扫描的输入是否是一个数字?在C中使用IF函数?
【发布时间】:2021-12-22 03:43:00
【问题描述】:

我只需要输入 1 到 3 个数值在 3 到 69 之间的数字。因此,当我输入与数字不同的内容时,程序应该 fprintf 在标准错误“输入不是数字”上。但我找不到如何编码的方法。我应该使用 if 函数。

#include <stdio.h>

int main()
{
int i=0;

while (scanf("%d", &i) == 1)
{
    
    if (i<3 || i>69)
    {
    fprintf(stderr,"Error: Input is too big or too small!");

    return 101;
    }
    if (ISNT A NUMBER)
    {
    fprintf(stderr,"Error: Input isnt a number!");

    return 100;
    }
}
 
return 0;
}

【问题讨论】:

标签: c if-statement scanf


【解决方案1】:

有很多方法可以正确地做到这一点:

使用scanf:

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

int get_num() {
    int i;

    printf("Enter a number between 3 and 69: ");
    fflush(stdout);
    if (scanf("%d", &i) != 1) {
        fprintf(stderr, "incorrect number of arguments, we need exactly one number (between 3 and 69)\n");
        return -1;
    }

    if( i < 3 || i > 69 ) {
        fprintf(stderr, "oops the number must be between [3, 69]\n");
        return -2;
    }

    return i;
}

void eat_trash() {
    int c;
    while((c = getchar())!= '\n' && c !=EOF);
}

int main() {
    int value;
    while ((value = get_num()) <= 0 ) {
        eat_trash();
    }
    printf("Got: %d\n", value);
}

有点额外,但有一些有趣但(可能有点傻)的东西:

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

int stdin_copy;

int get_num() {
    int i, rv = 0;
    static int err_count = 0;
    char *input = NULL;
    size_t len = 0;

    printf("Enter a number between 3 and 69: ");
    fflush(stdout);

    // gets a line (allocates memory we have to free)
    rv = getline(&input, &len, stdin);

    if ( rv > 3  ) {
        err_count++; // see if we have a lot of garbage incoming
        free(input);

        if (err_count < 3 ) {
            fprintf(stderr, "a number between 3 and 9 only needs two characters, try again. (%d tries left)\n", 3 - err_count);
            return -3;
        }
        // just stop dealing with this silly user.
        fprintf(stderr, "really? okay bye!\n");
        exit(127);
    }

    rv = sscanf(input, "%d", &i);
    free(input);

    if (rv != 1) {
        fprintf(stderr, "incorrect number of arguments, we need exactly one number (between 3 and 69)\n");
        return -1;
    }

    if( i < 3 || i > 69 ) {
        fprintf(stderr, "oops the number must be between [3, 69]\n");
        return -2;
    }

    return i;
}

void eat_trash() {
    fclose(stdin);
    stdin = fdopen(stdin_copy, "r");
    stdin_copy = dup(fileno(stdin));
}


int main() {
    int value;
    stdin_copy = dup(0);
    while ((value = get_num()) <= 0 ) {
        eat_trash();
    }
    printf("Got: %d\n", value);
}

需要注意的是垃圾的消耗方式。问题在于,如果用户在没有\n 的情况下推送输入,然后我们就会陷入 getline 函数的困境(它也会耗尽内存并且需要释放输入很烦人)。所以,

【讨论】:

  • 转角,"+12\n""003\n" 之类的输入失败,但接受 "3x\n"。一个出路是使用strtol(),检查转换成功,然后范围。
【解决方案2】:

有没有办法检查我扫描的输入是否是数字? C中的IF函数

最好的方法是使用fgets()(或getline(),如果有的话)读取用户输入,然后然后使用@987654323解析一个整数@。

scanf("%d", ...的麻烦包括

  • stdin 中保留非数字输入。
  • 没有读完整行。
  • 当第一行都是空白时读取多行。
  • 未检测到尾随的非数字输入。
  • int 溢出的未定义行为。

改为读取一个并形成一个字符串。然后解析字符串:

char *endptr;
long num = strtol(input_line_as_a_string, &endptr, 10);

if (input_line_as_a_string == endptr) {
  printf("No conversion happened. Input is non-numeric\n");
} else if (num < 3 || num > 69) {
  printf("Input %ld is out of range\n", num);
} else {
  while (isspace(*endptr)) endptr;  // skip trailing white-space
  if (*endptr != '\0') {
    printf("Input has trailing input\n");
  } else {
    printf("Success %ld\n", num);
  }
}

【讨论】:

    猜你喜欢
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2023-03-24
    • 2016-08-08
    • 2010-12-24
    相关资源
    最近更新 更多