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

 解析命令行选项

    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 132
static 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值