2015-02-12 98 views
1

我试图验证我的程序的用户在命令行中输入了一个有效的整数。我遇到了一个问题:它拒绝所有输入。检查命令行输入是否为有效整数(C)

这里就是我有

// Make sure input is a valid int 
char *ptr = NULL; 
long int input = strtol(argv[i+1], &ptr, 10); 
if(ptr == NULL){ 
    userMinInt = input; 
    minIntSet = true;  
} 
else 
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt); 
+0

我觉得http://stackoverflow.com/questions/19206660/how-to-write-own-isnumber-function回答了这个。 – peter 2015-02-12 03:15:13

+0

@peter啊,我明白了。所以你不检查你检查的空(char)0; – JayB 2015-02-12 03:18:47

+0

'我'是什么?确保你在做这个之前检查'i + 1 2015-02-12 03:23:53

回答

0

感谢Peter,我已经解决了这个问题。这里是新的工作代码:

// Make sure input is a valid int 
char *ptr = NULL; 
long int input = strtol(argv[i+1], &ptr, 10); 
if(ptr != NULL && *ptr == (char)0){ 
    userMinInt = input; 
    minIntSet = true; 
} 
else 
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt); 
+0

转换是不必要的,你可以在不改变程序行为的情况下将其删除。 – 2015-02-12 03:24:38

+0

@MattMcNabb Isnt(int)0在C中等于NULL吗? – JayB 2015-02-12 03:45:11

+1

不完全。 'NULL'是一个可扩展为'0'或'(void *)0'的宏,它应该用在需要指针的地方。这与'* ptr == 0'无关。 – 2015-02-12 04:28:18

1

代码正在检查结束指针是否为NULL。相反,代码应检查:

1)结束指针是否指向空字符'\0'
2)结束指针是否与开始不同?

低于其他检查:

char *start = argv[i+1]; // maybe should be argv[i] 
char *ptr; 
// set errno to 0 for subsequent check 
errno = 0; 
long int input = strtol(start, &ptr, 10); 
if (ptr == start) { 
    fprintf(stderr, "No conversion done.\n"); 
} 
else if (*ptr != 0) { 
    fprintf(stderr, "Extra data after the number.\n"); 
} 
else if (errno) { 
    fprintf(stderr, "Number outside long range.\n"); 
} 
else if (input < INT_MIN || input > INT_MAX) { 
    fprintf(stderr, "Number %ld outside int range.\n", input); 
} 
else { 
    printf("Number is %d.\n", (int) input); 
} 
+0

我认为'if(errno)'应该是'if((input == LONG_MIN || input == LONG_MAX)&& errno == ERANGE)' - 'errno'可以在成功时更改。 – mafso 2015-02-12 12:07:51

+0

@mafso同意提出的'if()'可以工作,但对它的需要不同意。调用strtol()会在范围错误上设置errno,否则它不会被改变:“如果函数调用了库函数调用,errno的值可以设置为非零在本国际标准的功能描述中没有记录使用'errno'。“ C11§7.53和'strtol()'spec包含:“...如果正确的值超出了可表示值的范围,...宏ERANGE的值存储在'errno'中。” §7.22.1.4 – chux 2015-02-12 15:49:46

+0

有趣。 Linux的手册页似乎与此矛盾(特别是代码示例)。标准C函数和POSIX或GNU函数可能有所不同吗?无论如何,我在这里确信这个案子。谢谢! – mafso 2015-02-12 16:13:07