C 使用 isdigit 检查 optarg 是否为数字
C Using isdigit to check if optarg is a digit
如果 optarg(标志 -s 之后的参数,来自 Getop 库)不是数字,我希望打印错误消息并终止程序,如果它是数字,则大小需要设置为optarg。我遇到的问题是,像 -s r 这样的命令会出现错误消息,-s 2 也会出现,这意味着它将 2 解释为字符串。
使用 for -s 2 进行调试
#1 printf("%d",atoi(optarg));
#2 printf("%d",isdigit(atoi(optarg)));
我得到第 1 行的整数值 2,
第 2 行的整数值为 0。
所以我想知道为什么 isdigit(atoi(optarg))) 给我一个 0,而 atoi(optarg) 给我一个 int。有没有更好的方法来检查 optarg 是否为 int?
int main (int argc, char *argv[]){
int size;
char option;
size = 0;
const char *optstring;
optstring = "rs:pih";
while ((option = getopt(argc, argv, optstring)) != EOF) {
switch (option) {
case 'r':
type_set = 1;
break;
**case 's':
capacity_set = 1;
if(isdigit(atoi(optarg))==0){
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0;
}**
else{
size = atoi(optarg);
}
break;
default{
return 0;
}
isdigit
获取一个字符并告诉您它是否为数字。 atoi
采用字符串 (char *) 和 returns 字符串表示的数字。因此,当您调用 isdigit(atoi(
... 时,您正在获取一个数字并将其视为一个字符。由于数字的字符代码为 48..57,因此除其中一个以外的任何数字都将 return 为假。
您可能需要 isdigit(*optarg)
——这将告诉您参数(字符串)的第一个字符是否为数字字符。当然,这只查看第一个字符,因此您可能需要 isdigit(optarg[0]) && optarg[1] == 0
。
如果你想接受 number 而不是 digit (而且只是一个数字),strtol
效果很好比 atoi
更好,因为它允许您检查故障。类似于:
char *end;
errno = 0;
size = strtol(optarg, &end, 10);
while (isspace(*end)) ++end;
if (errno || *end) {
// an error occurred on conversion, or there is extra cruft
// after a number in the argument.
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0; }
Chris Dodd 给出了很好的答案。另一种可能更简单的方法如下(假设您只想知道 optarg 是否是单个数字:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Assuming ASCII. "string" must be one character long and it
// must be a digit
int isSingleDigit( char *str )
{
return( (strlen(str) == 1) && ( *str >= '0' && *str <= '9' ) );
}
int main (void)
{
char *str = "a";
char *str1 = "9";
char *str2 = "10";
char *str3 = "1a";
printf( "%s %d\n", str, isSingleDigit(str));
printf( "%s %d\n", str1, isSingleDigit(str1));
printf( "%s %d\n", str2, isSingleDigit(str2));
printf( "%s %d\n", str3, isSingleDigit(str3));
return 0;
}
输出:
a 0
9 1
10 0
1a 0
如果 optarg(标志 -s 之后的参数,来自 Getop 库)不是数字,我希望打印错误消息并终止程序,如果它是数字,则大小需要设置为optarg。我遇到的问题是,像 -s r 这样的命令会出现错误消息,-s 2 也会出现,这意味着它将 2 解释为字符串。
使用 for -s 2 进行调试
#1 printf("%d",atoi(optarg));
#2 printf("%d",isdigit(atoi(optarg)));
我得到第 1 行的整数值 2, 第 2 行的整数值为 0。
所以我想知道为什么 isdigit(atoi(optarg))) 给我一个 0,而 atoi(optarg) 给我一个 int。有没有更好的方法来检查 optarg 是否为 int?
int main (int argc, char *argv[]){
int size;
char option;
size = 0;
const char *optstring;
optstring = "rs:pih";
while ((option = getopt(argc, argv, optstring)) != EOF) {
switch (option) {
case 'r':
type_set = 1;
break;
**case 's':
capacity_set = 1;
if(isdigit(atoi(optarg))==0){
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0;
}**
else{
size = atoi(optarg);
}
break;
default{
return 0;
}
isdigit
获取一个字符并告诉您它是否为数字。 atoi
采用字符串 (char *) 和 returns 字符串表示的数字。因此,当您调用 isdigit(atoi(
... 时,您正在获取一个数字并将其视为一个字符。由于数字的字符代码为 48..57,因此除其中一个以外的任何数字都将 return 为假。
您可能需要 isdigit(*optarg)
——这将告诉您参数(字符串)的第一个字符是否为数字字符。当然,这只查看第一个字符,因此您可能需要 isdigit(optarg[0]) && optarg[1] == 0
。
如果你想接受 number 而不是 digit (而且只是一个数字),strtol
效果很好比 atoi
更好,因为它允许您检查故障。类似于:
char *end;
errno = 0;
size = strtol(optarg, &end, 10);
while (isspace(*end)) ++end;
if (errno || *end) {
// an error occurred on conversion, or there is extra cruft
// after a number in the argument.
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0; }
Chris Dodd 给出了很好的答案。另一种可能更简单的方法如下(假设您只想知道 optarg 是否是单个数字:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Assuming ASCII. "string" must be one character long and it
// must be a digit
int isSingleDigit( char *str )
{
return( (strlen(str) == 1) && ( *str >= '0' && *str <= '9' ) );
}
int main (void)
{
char *str = "a";
char *str1 = "9";
char *str2 = "10";
char *str3 = "1a";
printf( "%s %d\n", str, isSingleDigit(str));
printf( "%s %d\n", str1, isSingleDigit(str1));
printf( "%s %d\n", str2, isSingleDigit(str2));
printf( "%s %d\n", str3, isSingleDigit(str3));
return 0;
}
输出:
a 0
9 1
10 0
1a 0