(Michael Kerrisk)Linux系统编程手册读书笔记(一)-----解析命令行选项

来源:互联网 发布:手机端点击图片放大js 编辑:程序博客网 时间:2024/04/29 09:16

 解析命令行选项

    1.  函数getopt可以用来解析命令行选项:

函数原型:int getopt(int argc,char *const argv[],const char *optstring)

参数:1.argc,argv 是从main函数的参数列表中获取的。

2.optstring 指定了函数getopt应寻找的命令行选项集合,该参数由一组字符组成,每个字符标识一个选项。getopt至少应该接受62个字符[a-zA-Z0-9]作为选项;:、?、和-这几个是对getopt有着特殊意义的字符;每个选项字符后面跟着一个冒号字符(:),表示这个选项带有一个参数。

返回值:返回得到选项字符的int值,当返回值为-1时,则表示目前没有更多的选项可解析了(已到达选项列表的结尾)。

     2.    函数getopt的全局变量:

2.1  optind:指向参数列表argv中未处理的下一个元素(会跳过选项带有的参数)。

2.2  optopt:返回出现错误的选项字符。

2.3  optstring:指向选项的参数。

2.4  opterr:默认值为1;当其值为0时,可用来禁止显示由getopt函数打印出来的错误消息。

     3.  

函数getopt错误上报的几种行为错误上报的方法getopt()会显示错误消息吗针对未识别的选项产生的返回值针对缺少参数产生的返回值

默认(opterr == 1)

Y

?

?

opterr == 0

N

?

?

在optstring中将第一个字符设为:

N

?

:

    4.程序实例:

#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>#include<string.h>#include<stdarg.h>#include<sys/stat.h>#include<ctype.h>#define printable(ch)(isprint((unsigned char)ch) ? ch : '#')#define MAX_ENAME 132static char *ename[] = {        /*   0 */ "",         /*   1 */ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO","ENXIO",         /*   7 */ "E2BIG", "ENOEXEC", "EBADF", "ECHILD",         /*  11 */ "EAGAIN/EWOULDBLOCK", "ENOMEM","EACCES", "EFAULT",         /*  15 */ "ENOTBLK", "EBUSY", "EEXIST","EXDEV", "ENODEV",         /*  20 */ "ENOTDIR", "EISDIR","EINVAL", "ENFILE", "EMFILE",         /*  25 */ "ENOTTY", "ETXTBSY","EFBIG", "ENOSPC", "ESPIPE",         /*  30 */ "EROFS", "EMLINK","EPIPE", "EDOM", "ERANGE",         /*  35 */ "EDEADLK/EDEADLOCK", "ENAMETOOLONG", "ENOLCK", "ENOSYS",         /*  39 */ "ENOTEMPTY","ELOOP", "", "ENOMSG", "EIDRM", "ECHRNG",         /*  45 */ "EL2NSYNC","EL3HLT", "EL3RST", "ELNRNG", "EUNATCH",         /*  50 */"ENOCSI", "EL2HLT", "EBADE", "EBADR", "EXFULL", "ENOANO",         /*  56 */"EBADRQC", "EBADSLT", "", "EBFONT", "ENOSTR", "ENODATA",         /*  62 */"ETIME", "ENOSR", "ENONET", "ENOPKG", "EREMOTE",         /*  67 */"ENOLINK", "EADV", "ESRMNT", "ECOMM", "EPROTO",         /*  72 */"EMULTIHOP", "EDOTDOT", "EBADMSG", "EOVERFLOW",         /*  76 */"ENOTUNIQ", "EBADFD", "EREMCHG", "ELIBACC", "ELIBBAD",         /*  81 */"ELIBSCN", "ELIBMAX", "ELIBEXEC", "EILSEQ", "ERESTART",         /*  86 */"ESTRPIPE", "EUSERS", "ENOTSOCK", "EDESTADDRREQ",         /*  90 */"EMSGSIZE", "EPROTOTYPE", "ENOPROTOOPT",         /*  93 */"EPROTONOSUPPORT", "ESOCKTNOSUPPORT",         /*  95 */"EOPNOTSUPP/ENOTSUP", "EPFNOSUPPORT", "EAFNOSUPPORT",         /*  98 */"EADDRINUSE", "EADDRNOTAVAIL", "ENETDOWN", "ENETUNREACH",         /* 102 */"ENETRESET", "ECONNABORTED", "ECONNRESET", "ENOBUFS",         /* 106 */"EISCONN", "ENOTCONN", "ESHUTDOWN", "ETOOMANYREFS",         /* 110 */"ETIMEDOUT", "ECONNREFUSED", "EHOSTDOWN", "EHOSTUNREACH",         /* 114 */"EALREADY", "EINPROGRESS", "ESTALE", "EUCLEAN",         /* 118 */"ENOTNAM", "ENAVAIL", "EISNAM", "EREMOTEIO", "EDQUOT",         /* 123 */"ENOMEDIUM", "EMEDIUMTYPE", "ECANCELED", "ENOKEY",         /* 127 */"EKEYEXPIRED", "EKEYREVOKED", "EKEYREJECTED",         /* 130 */"EOWNERDEAD", "ENOTRECOVERABLE", "ERFKILL"};typedef enum {FALSE,TRUE} Boolean;static void usageError(char *,char *,int);static void outputError(Boolean ,int ,Boolean ,const char *,va_list );static void terminate(Boolean );void fatal(const char *format,...);int main(int ac ,char *av[]){    int opt;    char *pstr;    int xfnd;    xfnd = 0;    pstr = NULL;    while((opt = getopt(ac,av,":p:x")) != -1)    {        printf("opt = %3d(%c);optind = %d",opt,printable(opt),optind);        if(opt == '?' || opt == ':')            printf(";optopt = %3d(%c)",optopt,printable(optopt));        printf("\n");        switch(opt)        {            case 'p':                 pstr = optarg;                break;            case 'x':                xfnd++;                break;            case ':':                usageError(av[0],"Missing argument",optopt);            case '?':                usageError(av[0],"Unrecognized option",optopt);            default:                fatal("Unexpected case in switch()");        }    }    if(xfnd != 0)        printf("-x was specified (count = %d)\n",xfnd);    if(pstr != NULL)        printf("-p was specified with the value \"%s\"\n",pstr);    if(optind < ac)        printf("First nonoption argument is \"%s\" at av[%d]\n",av[optind],optind);    exit(EXIT_SUCCESS);}static void usageError(char *progName,char *msg,int opt){    if(msg != NULL && opt != 0)        fprintf(stderr,"%s(-%c)\n",msg,printable(opt));    fprintf(stderr,"Usage: %s [-p arg] [-x]\n",progName);    exit(EXIT_FAILURE);}void fatal(const char *format,...){    va_list argList;    va_start(argList,format);    outputError(FALSE,0,TRUE,format,argList);    va_end(argList);    terminate(TRUE);}static void outputError(Boolean useErr,int err,Boolean flushStdout,const char *format,va_list ap){    #define BUF_SIZE 500    char buf[BUF_SIZE],userMsg[BUF_SIZE],errText[BUF_SIZE];    vsnprintf(userMsg,BUF_SIZE,format,ap);    if(useErr)        snprintf(errText,BUF_SIZE,"[%s %s]",(err > 0 && err < MAX_ENAME) ? ename[err] : "?UNKNOWN?",strerror(err));    else        snprintf(errText,BUF_SIZE,":");    snprintf(buf,BUF_SIZE,"ERROR %s %s\n",errText,userMsg);    if(flushStdout)        fflush(stdout);    fputs(buf,stderr);    fflush(stderr);}static void terminate(Boolean useExit3){    char *s;    s = getenv("EF_DUMPCORE");    if(s != NULL && s != '\0')        abort();    else if(useExit3)        exit(EXIT_FAILURE);    else        _exit(EXIT_FAILURE);}


 

 

 

 

 

0 0
原创粉丝点击