C 中的命令行参数验证

Ohh*_*hhh 1 c int

我有一个程序需要int从命令行获取用户

int main(int argc, char* argv[])
Run Code Online (Sandbox Code Playgroud)

我唯一的问题是我需要检查是否argvint. 如果不是,我需要返回一个错误。我怎样才能做到这一点?我必须int在使用之前检查输入是否为 an atoi。有人能帮我吗?

Cra*_*tey 8

这是一种使用strtol和检查字符串结尾的方法:

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

int
main(int argc,char **argv)
{
    char *cp;
    long lval;
    int val;

    // skip over program name
    --argc;
    ++argv;

    if (argc < 1) {
        fprintf(stderr,"main: no argument specified\n");
        exit(1);
    }

    cp = *argv;
    if (*cp == 0) {
        fprintf(stderr,"main: argument an empty string\n");
        exit(1);
    }

    lval = strtol(cp,&cp,10);
    if (*cp != 0) {
        fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
            *argv,cp);
        exit(1);
    }

    val = (int) lval;

    // NOTE: just going for extra credit here ;-)
    // ensure number fits in a int (since strtol returns long and that's 64
    // bits on a 64 bit machine)
#if 1
    if (val != lval) {
        fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
            *argv,lval,val);
        exit(1);
    }
#endif

    printf("val=%d\n",val);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:

次要:代码未检测到 strtol() 的转换溢出 代码错误地假定了 long 大于 int 的范围。如果范围相同,if (val != lval)则始终为真。建议看errno, INT_MAX,INT_MIN

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>

int
main(int argc,char **argv)
{
    char *cp;
    long lval;
    int val;

    // skip over program name
    --argc;
    ++argv;

    if (argc < 1) {
        fprintf(stderr,"main: no argument specified\n");
        exit(1);
    }

    cp = *argv;
    if (*cp == 0) {
        fprintf(stderr,"main: argument an empty string\n");
        exit(1);
    }

    errno = 0;
    lval = strtol(cp,&cp,10);

    if (*cp != 0) {
        fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
            *argv,cp);
        exit(1);
    }

    // on a 32 bit machine, entering 2147483648 will produce a non-zero errno
    if (errno) {
        fprintf(stderr,"main: argument '%s' parse error -- '%s'\n",
            *argv,strerror(errno));
        exit(1);
    }

    // on a 64 bit machine, entering 2147483648 will not produce an error, so
    // we should check the range ourselves
    if ((lval < INT_MIN) || (lval > INT_MAX)) {
        fprintf(stderr,"main: argument '%s' range error -- %ld outside of range (%ld to %ld)\n",
            *argv,lval,(long) INT_MIN,(long) INT_MAX);
        exit(1);
    }

    val = (int) lval;

    // NOTE: just going for extra credit here ;-)
    // ensure number fits in a int (since strtol returns long and that's 64
    // bits on a 64 bit machine)
    // FIXME -- with above tests this can never be true (i.e. fault), so
    // I've nop'ed it -- left in to show prior/original test
#if 0
    if (val != lval) {
        fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
            *argv,lval,val);
        exit(1);
    }
#endif

    printf("val=%d\n",val);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)