使用isdigit和if

问题描述 投票:0回答:3
int main()
{
 int f;
 printf("Type your age");
 scanf("%d", &f);
 if(!isdigit(f))
  {
   printf("Digit");
  }
  else
  {
   printf("Is not a digit");
  }
return 0;
}

无论打字的6还是a总是向我显示“数字”消息

c
3个回答
3
投票

isdigit()应该通过char而不是int。你的if-else逻辑是相反的:

int main() {
    char f;

    printf("Type your age");
    scanf("%c", &f);

    if (isdigit(f)) {
        printf("Digit");
    } else {
        printf("Is not a digit");
    }

    return 0;
}

正如评论中所提到的,这只适用于单个数字时代。验证输入是“C”标签下的一个主要主题,搜索将揭示更多强大验证的许多方法。


2
投票

%d是一个整数说明符。将int f更改为char f并将其解析为角色。你总是将int传递给isdigit,这就是为什么它总是如此。


0
投票

实际上没有必要在这里使用isdigit,因为scanf%d格式说明符已经保证字符将是带有可选前导符号的数字。还有一个单独的说明符可以摆脱领先的标志%u

如果您输入的内容格式不正确,scanf会告诉您(因为它返回成功扫描的项目数)。

因此,对于一个简单的解决方案,您可以使用以下内容:

unsigned int age;
if (scanf("%u", &age) == 1) {
    puts("Not a valid age");
    return 1;
}
// Now it's a valid uint, though you may want to catch large values.

如果你想要强大的代码,你可能需要付出比单线scanf("%d")更多的努力 - 它适用于一次性或丢弃程序,但它对于用于实际系统的代码有严重的缺点。

首先,我将在this answer(a)中使用优秀的字符串输入例程 - 它几乎提供了提示和检查用户输入所需的一切。

一旦你将输入作为字符串,strtoul允许你进行与scanf相同类型的转换,但同时也能确保线上没有尾随垃圾。 This answer(来自同一作者)提供了这样做的手段。

将所有这些结合在一起,您可以使用以下内容:

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

// Code to robustly get input from user.

#define OK       0      // Return codes - okay.
#define NO_INPUT 1      //              - no input given.
#define TOO_LONG 2      //              - input was too long.

static int getLine (
    char *prmpt,        // The prompt to use (NULL means no prompt).
    char *buff,         // The buffer to populate.
    size_t sz           // The size of the buffer.
) {
    int ch, extra;

    // Get line with buffer overrun protection.

    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.

    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.

    buff[strlen(buff)-1] = '\0';
    return OK;
}

// Code to check string is valid unsigned integer and within range.
// Returns true if it passed all checks, false otherwise.

static int validateStrAsUInt(
    char *str,                   // String to evaluate.
    unsigned int minVal,         // Minimum allowed value.
    unsigned int maxVal,         // Maximum allowed value.
    unsigned int *pResult        // Address of item to take value.
) {
    char *nextChar;
    unsigned long retVal = strtoul (str, &nextChar, 10);

    // Ensure we used the *whole* string and that it wasn't empty.

    if ((nextChar == str) || (*nextChar != '\0'))
        return 0;

    // Ensure it's within range.

    if ((retVal < minVal) || (retVal > maxVal))
        return 0;

    // It's okay, send it back to caller.

    *pResult = retVal;
    return 1;
}

// Code for testing above functions.

int main(void) {
    int retCode;
    unsigned int age;
    char buff[20];

    // Get it as string, detecting input errors.

    retCode = getLine ("Enter your age> ", buff, sizeof(buff));

    if (retCode == NO_INPUT) {
        printf ("\nError, no input given.\n");
        return 1;
    }

    if (retCode == TOO_LONG) {
        printf ("Error, input too long [%s]\n", buff);
        return 1;
    }

    // Check string is valid age.

    if (! validateStrAsUInt(buff, 0, 150, &age)) {
        printf("Not a valid age (0-150)\n");
        return 1;
    }

    // It's okay, print and exit.

    printf("Age is valid: %u\n", age);
    return 0;
}

(a)我可靠地告知作者其实很聪明,而且非常好看:-)

© www.soinside.com 2019 - 2024. All rights reserved.