解析命令行参数

来源:互联网 发布:美工设计团队 编辑:程序博客网 时间:2024/05/22 07:52
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>


int make_argv(const char *astr, const char *delimiters, char ***argvp);

void free_argv(char **argvp);


int main(int argc, char *argv[])
{
    char delim[] = " \t";
    int i;
    char **myargv;
    int numtokens;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s string\n",argv[0]);
        return 1;
    }

    if ((numtokens = make_argv(argv[1], delim, &myargv)) == -1)
    {
        fprintf(stderr, "Failed to construct an argument array for %s\n",argv[1]);
        return -1;
    }

    printf("The argument array contains:\n");
    for(i = 0; i < numtokens; ++i)

        printf("%d:%s\n", i, myargv[i]);

    free_argv(myargv);

    return 0;
}

//Name: make_argv
//Description: 利用分割标示符(delimiters)解析命令行参数字符串(astr),并将参数存入参数数组*argvp
int make_argv(const char *astr, const char *delimiters, char ***argvp)
{
    int error;
    int i;
    int numtokens;
    const char *snew;
    char *t, *oldt;

    if ((astr == NULL) || (delimiters == NULL) || (argvp == NULL))
    {
        errno = EINVAL;
        return -1;
    }

    *argvp = NULL;
    snew = astr + strspn(astr, delimiters);    //去除前面的分割标示符
    if ((oldt = t = malloc(strlen(snew) + 1)) == NULL)    //申请空间并保存地址oldt
        return -1;
    strcpy(t, snew);    //初始化待处理命令行
    //求参数个数numtokens,strsep是字符串分割函数
    for(numtokens = 0; strsep(&t, delimiters) != NULL; ++numtokens)
    {
            t = t + strspn(t, delimiters);    //去除前面的分割标示符
    }
    //根据numtokens为*argvp申请空间(参数数组)
    if ((*argvp = malloc((numtokens + 1) * sizeof(char *))) == NULL)
    {
        error = errno;
        free(t);
        errno = error;
        return -1;
    }
    
    if (numtokens == 0)
        free(t);
    else
    {
        t = oldt;
        strcpy(t, snew);    //初始化待处理命令行
    //将解析的参数,存入参数数组*argvp中
        for(i = 0; i < numtokens; ++i)
        {
            *(*argvp + i) = strsep(&t, delimiters);
            if(t)
                t = t + strspn(t, delimiters);    //去除前面的分割标示符
        }
    }

    *(*argvp + numtokens) = NULL;
    return numtokens;
    

}

void free_argv(char **argvp)
{
    if (argvp == NULL)
        return;
    if (*argvp != NULL)
        free(*argvp);
    free(argvp);
}


原创粉丝点击