C++ 在C+中模拟shell参数解析器+;

C++ 在C+中模拟shell参数解析器+;,c++,regex,command-line,command-line-arguments,C++,Regex,Command Line,Command Line Arguments,我一直在研究一个模仿shell终端的程序,我遇到了一个比我预期的更难实现的问题。基本上,我正在尝试分割参数,就像shell如何传递到其可执行文件一样。因此,想象一个输入,如: $>。/foo一些参数 我们希望传递给程序的参数是类似于数组的(假设为C/C++): char**argv={“foo”,“某些”“参数”} 但是,如果论点是: $>。/foo“我的名字是foo”栏 阵列将是: char**argv={“foo”,“我的名字是foo”,“bar”} 有谁能建议一种有效的方法来实现这一点,比

我一直在研究一个模仿shell终端的程序,我遇到了一个比我预期的更难实现的问题。基本上,我正在尝试分割参数,就像shell如何传递到其可执行文件一样。因此,想象一个输入,如:

$>。/foo一些参数

我们希望传递给程序的参数是类似于数组的(假设为C/C++):

char**argv={“foo”,“某些”“参数”}

但是,如果论点是:

$>。/foo“我的名字是foo”栏

阵列将是:

char**argv={“foo”,“我的名字是foo”,“bar”}

有谁能建议一种有效的方法来实现这一点,比如界面如下:

vector splitArgs(字符串allArgs)
字符串[]拆分参数(字符串allArgs)


当然,我可以简单地在“阅读单词”和“阅读引用文本”的状态之间进行迭代和切换,但我觉得这并不像它可能的那样有效。我还玩弄了正则表达式的想法,但我对C++中如何做到这一点还不太熟悉。对于这个项目,如果有帮助的话,我也安装了boost库

谢谢!
RR

只需将整个字符串传递给shell就可以满足您的需要:

例如:

不过,这并不是最好的解决方案


更好的方法似乎是写一个并将其传递给一个

我有时仍然使用这个普通的C实用函数来实现这一点。我主要在标准库非常有限的嵌入式系统上使用它,因此大多数代码可以使用标准库控件更改为更高效,但基本技术应该保持不变,即在解析之前标记字符串的引用部分,然后通过在标记上拆分,将字符串拆分为单独的标记,最后从各个部分中删除引号

/**
 * Split a line into separate words.
 */
static void splitLine(char *pLine, char **pArgs) {
    char *pTmp = strchr(pLine, ' ');

    if (pTmp) {
        *pTmp = '\0';
        pTmp++;
        while ((*pTmp) && (*pTmp == ' ')) {
            pTmp++;
        }
        if (*pTmp == '\0') {
            pTmp = NULL;
        }
    }
    *pArgs = pTmp;
}



/**
 * Breaks up a line into multiple arguments.
 *
 * @param io_pLine Line to be broken up.
 * @param o_pArgc Number of components found.
 * @param io_pargc Array of individual components
 */
static void parseArguments(char *io_pLine, int *o_pArgc, char **o_pArgv) {
    char *pNext = io_pLine;
    size_t i;
    int j;
    int quoted = 0;
    size_t len = strlen(io_pLine);

    // Protect spaces inside quotes, but lose the quotes
    for(i = 0; i < len; i++) {
        if ((!quoted) && ('"' == io_pLine[i])) {
            quoted = 1;
            io_pLine[i] = ' ';
        } else if ((quoted) && ('"' == io_pLine[i])) {
            quoted = 0;
            io_pLine[i] = ' ';
        } else if ((quoted) && (' ' == io_pLine[i])) {
            io_pLine[i] = '\1';
        }
    }

    // init
    MY_memset(o_pArgv, 0x00, sizeof(char*) * C_MAXARGS);
    *o_pArgc = 1;
    o_pArgv[0] = io_pLine;

    while ((NULL != pNext) && (*o_pArgc < C_MAXARGS)) {
        splitLine(pNext, &(o_pArgv[*o_pArgc]));
        pNext = o_pArgv[*o_pArgc];

        if (NULL != o_pArgv[*o_pArgc]) {
            *o_pArgc += 1;
        }
    }

    for(j = 0; j < *o_pArgc; j++) {
        len = strlen(o_pArgv[j]);
        for(i = 0; i < len; i++) {
            if('\1' == o_pArgv[j][i]) {
                o_pArgv[j][i] = ' ';
            }
        }
    }
}
/**
*把一行字分开。
*/
静态空隙分割线(字符*pLine,字符**pArgs){
char*pTmp=strchr(pLine,”);
如果(pTmp){
*pTmp='\0';
pTmp++;
而((*pTmp)和(*pTmp=''){
pTmp++;
}
如果(*pTmp=='\0'){
pTmp=NULL;
}
}
*pArgs=pTmp;
}
/**
*将一行拆分为多个参数。
*
*@param io_pLine线路将被断开。
*@param o_pArgc找到的组件数。
*@param io_单个组件的pargc数组
*/
静态void parseArguments(char*io\u pLine、int*o\u pArgc、char**o\u pArgv){
char*pNext=io_pLine;
尺寸i;
int j;
int=0;
尺寸长度=标准长度(标准线);
//保护引号内的空格,但丢失引号
对于(i=0;i
“但我觉得这并没有它可能的那么有效”。。。真的,你最好只是做它,并得到一个工作壳。不管怎样,既然你已经问过了,用boost标记器检查解决方案。只需一步一步地检查每个字符,看看你有什么。我在C#中是怎么做到的。我不确定RegEx是否能满足你们的需要。太好了,谢谢你们。我想这就是我想知道的。实现它是第二步。第一步是定义它。查看您最喜欢的shell的文档,以找到可以使用的定义。需要考虑的事项:多种引号;圆括号;I/O重定向;反斜杠。(还有,你真的想去掉第一个标记的前两个字符吗?为什么?)
/**
 * Split a line into separate words.
 */
static void splitLine(char *pLine, char **pArgs) {
    char *pTmp = strchr(pLine, ' ');

    if (pTmp) {
        *pTmp = '\0';
        pTmp++;
        while ((*pTmp) && (*pTmp == ' ')) {
            pTmp++;
        }
        if (*pTmp == '\0') {
            pTmp = NULL;
        }
    }
    *pArgs = pTmp;
}



/**
 * Breaks up a line into multiple arguments.
 *
 * @param io_pLine Line to be broken up.
 * @param o_pArgc Number of components found.
 * @param io_pargc Array of individual components
 */
static void parseArguments(char *io_pLine, int *o_pArgc, char **o_pArgv) {
    char *pNext = io_pLine;
    size_t i;
    int j;
    int quoted = 0;
    size_t len = strlen(io_pLine);

    // Protect spaces inside quotes, but lose the quotes
    for(i = 0; i < len; i++) {
        if ((!quoted) && ('"' == io_pLine[i])) {
            quoted = 1;
            io_pLine[i] = ' ';
        } else if ((quoted) && ('"' == io_pLine[i])) {
            quoted = 0;
            io_pLine[i] = ' ';
        } else if ((quoted) && (' ' == io_pLine[i])) {
            io_pLine[i] = '\1';
        }
    }

    // init
    MY_memset(o_pArgv, 0x00, sizeof(char*) * C_MAXARGS);
    *o_pArgc = 1;
    o_pArgv[0] = io_pLine;

    while ((NULL != pNext) && (*o_pArgc < C_MAXARGS)) {
        splitLine(pNext, &(o_pArgv[*o_pArgc]));
        pNext = o_pArgv[*o_pArgc];

        if (NULL != o_pArgv[*o_pArgc]) {
            *o_pArgc += 1;
        }
    }

    for(j = 0; j < *o_pArgc; j++) {
        len = strlen(o_pArgv[j]);
        for(i = 0; i < len; i++) {
            if('\1' == o_pArgv[j][i]) {
                o_pArgv[j][i] = ' ';
            }
        }
    }
}