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
总是向我显示“数字”消息
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”标签下的一个主要主题,搜索将揭示更多强大验证的许多方法。
%d
是一个整数说明符。将int f
更改为char f
并将其解析为角色。你总是将int
传递给isdigit
,这就是为什么它总是如此。
实际上没有必要在这里使用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)我可靠地告知作者其实很聪明,而且非常好看:-)