命令行解析模板

  別人若是本身要寫一個東西,不是立刻打開ide開始寫代碼,而是去網上搜索一下看看是否已經相關的代碼,若是有相同的功能代碼直接複製過來用就能夠了,若是是有類似的能夠改改用,這樣能提升開發效率。linux

  因此在學習怎麼寫代碼以前我先嚐試了一下怎麼使用別人寫過的代碼。我想實現的功能是一個命令行下的程序模板,可以支持對輸入的命令行參數進行解析。我首先從網上進行了一下搜索,找到說在linux下有系統提供的函數getopt,但在windows下好像沒有,有的說能夠直接將linux下的文件拷貝過來直接使用,但好像是須要進行對文件頭進行修改,代碼下回來看了看不知道該怎麼修改,因而又從網上直接下載了一個別人寫過的代碼直接拿過來使用。windows

  網上下回來的代碼是一個.c文件,主要的功能是用來分析命令行參數,函數有三個參數:前兩個參數分別表明參數個數和內容,跟main()函數的命令行參數是同樣的。第三個參數是選項字符串, 告知 getopt()能夠處理哪一個選項以及哪一個選項須要參數,若是選項字符串裏的字母后接着冒號「:」,則表示還有相關的參數,全局變量optarg 即會指向此額外參數。ide

optstring中的指定的內容的意義補充說明:

1.單個字符,表示選項。
2.單個字符後接一個冒號:表示該選項後必須跟一個參數。參數能夠緊跟在選項後也能夠以空格隔開。該參數的指針將賦給optarg。
3 單個字符後跟兩個冒號,表示該選項後能夠跟一個參數,也能夠不跟。若是跟一個參數,參數必須緊跟在選項後不能以空格隔開。該參數的指針賦給optarg。(如上例中的e::,若是沒有跟參數,則optarg = NULL)

 

  下載的getopt.c文件內容以下,因爲避免篇幅過長,我省略掉了頭部的部分註釋信息,完整的文件信息能夠在附件中查看。函數

#include <stdio.h>                  /* for EOF */
#include <string.h>                 /* for strchr() */
 
 
/* static (global) variables that are specified as exported by getopt() */
char *optarg = NULL;    /* pointer to the start of the option argument  */
int   optind = 1;       /* number of the next argv[] to be evaluated    */
int   opterr = 1;       /* non-zero if a question mark should be returned
                           when a non-valid option character is detected */
 
/* handle possible future character set concerns by putting this in a macro */
#define _next_char(string)  (char)(*(string+1))
 
int getopt(int argc, char *argv[], char *opstring)
{
    static char *pIndexPosition = NULL; /* place inside current argv string */
    char *pArgString = NULL;        /* where to start from next */
    char *pOptString;               /* the string in our program */
 
 
    if (pIndexPosition != NULL) {
        /* we last left off inside an argv string */
        if (*(++pIndexPosition)) {
            /* there is more to come in the most recent argv */
            pArgString = pIndexPosition;
        }
    }
 
    if (pArgString == NULL) {
        /* we didn't leave off in the middle of an argv string */
        if (optind >= argc) {
            /* more command-line arguments than the argument count */
            pIndexPosition = NULL;  /* not in the middle of anything */
            return EOF;             /* used up all command-line arguments */
        }
 
        /*---------------------------------------------------------------------
         * If the next argv[] is not an option, there can be no more options.
         *-------------------------------------------------------------------*/
        pArgString = argv[optind++]; /* set this to the next argument ptr */
 
        if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */
            ('-' != *pArgString)) {
            --optind;               /* point to current arg once we're done */
            optarg = NULL;          /* no argument follows the option */
            pIndexPosition = NULL;  /* not in the middle of anything */
            return EOF;             /* used up all the command-line flags */
        }
 
        /* check for special end-of-flags markers */
        if ((strcmp(pArgString, "-") == 0) ||
            (strcmp(pArgString, "--") == 0)) {
            optarg = NULL;          /* no argument follows the option */
            pIndexPosition = NULL;  /* not in the middle of anything */
            return EOF;             /* encountered the special flag */
        }
 
        pArgString++;               /* look past the / or - */
    }
 
    if (':' == *pArgString) {       /* is it a colon? */
        /*---------------------------------------------------------------------
         * Rare case: if opterr is non-zero, return a question mark;
         * otherwise, just return the colon we're on.
         *-------------------------------------------------------------------*/
        return (opterr ? (int)'?' : (int)':');
    }
    else if ((pOptString = strchr(opstring, *pArgString)) == 0) {
        /*---------------------------------------------------------------------
         * The letter on the command-line wasn't any good.
         *-------------------------------------------------------------------*/
        optarg = NULL;              /* no argument follows the option */
        pIndexPosition = NULL;      /* not in the middle of anything */
        return (opterr ? (int)'?' : (int)*pArgString);
    }
    else {
        /*---------------------------------------------------------------------
         * The letter on the command-line matches one we expect to see
         *-------------------------------------------------------------------*/
        if (':' == _next_char(pOptString)) { /* is the next letter a colon? */
            /* It is a colon.  Look for an argument string. */
            if ('\0' != _next_char(pArgString)) {  /* argument in this argv? */
                optarg = &pArgString[1];   /* Yes, it is */
            }
            else {
                /*-------------------------------------------------------------
                 * The argument string must be in the next argv.
                 * But, what if there is none (bad input from the user)?
                 * In that case, return the letter, and optarg as NULL.
                 *-----------------------------------------------------------*/
                if (optind < argc)
                    optarg = argv[optind++];
                else {
                    optarg = NULL;
                    return (opterr ? (int)'?' : (int)*pArgString);
                }
            }
            pIndexPosition = NULL;  /* not in the middle of anything */
        }
        else {
            /* it's not a colon, so just return the letter */
            optarg = NULL;          /* no argument follows the option */
            pIndexPosition = pArgString;    /* point to the letter we're on */
        }
        return (int)*pArgString;    /* return the letter that matched */
    }
}

  程序主函數代碼只是包含了上面的getopt.c文件,而後調用了getopt函數解析並打印了命令行參數,並無執行其餘任何操做。getopt.cpp文件代碼以下:學習

#include "stdafx.h"
#include "getopt.c"

int main(int argc, char* argv[])
{
    int ch;
    //opterr = 0;
    while((ch = getopt(argc,argv,"a:b:c:d:"))!= -1)
    {
        switch(ch)
        {
        case 'a': printf("option a:'%s'\n",optarg); break;
        case 'b': printf("option b:'%s'\n",optarg); break;
        case 'c': printf("option c:'%s'\n",optarg); break;
        case 'd': printf("option d:'%s'\n",optarg); break;
        default: printf("other option :%c\n",ch);
        }
    }
    return 0;
}

  將代碼編譯後沒有錯誤。在命令行中調用運行,獲得的結果以下:this

D:\cproject\getopt\Release>getopt.exe -a f -b fawef -c fawe -d fawef
option a:'f'
option b:'fawef'
option c:'fawe'
option d:'fawef'

D:\cproject\getopt\Release>

 

btw:lua

代碼編寫使用的ide是VC++ 6.0。spa

相關代碼的下載地址命令行

相關文章
相關標籤/搜索