char拆分和解析

时间:2013-07-31 05:04:52

标签: c parsing strtok split

所以我试图设置一个能正确解析以下输入类型的函数(注意这个输入是乱七八糟的,只是为了试图说明我的例子)

"./test script";ls -a -o;mkdir "te>st";ls > somefile.txt

每个命令用';'分隔并且每个参数由空格''分隔,除非它们被包裹在“”中,在这种情况下它们应被视为字面或整体。 IE我想要的输出是

cmd:“。/ test script”

cmd:ls args [2] {-a,-o}

cmd:mkdir args [1] {“te> st”}

cmd:ls args [2] {>,somefile.txt}

我试过通过分裂它;首先,然后通过'',但第一个例子失败(包裹在“”所以应该被认为是完整的),我有一些麻烦c,因为我不是很熟悉这种语言,任何人都可以帮忙吗?这就是我到目前为止所拥有的

    // Commands split with ; 
    char *cmdSplitToken = strtok(srcPointer, ";");

    // Store commands seperately so we can deal with them one by one
    while(cmdSplitToken != NULL) {      
        cmds[cmdCount++] = cmdSplitToken;
        cmdSplitToken = strtok(NULL, ";");
    }

    // Loop over commands and gather arguments
    for(int i = 0; i < cmdCount; i++) {     
        // args split with ' '
        char *argSplitToken = strtok(cmds[i], " "); 
        int argCount = 0;
        while(argSplitToken != NULL) {      
            printf("arg %s\n", argSplitToken);
            argCount++;
            argSplitToken = strtok(NULL, " ");
        }
    }

2 个答案:

答案 0 :(得分:0)

当你必须处理复杂规则(带有双引号的字段),制作自己的函数或使用某个库时,避免使用strtok,我建议你去看libcsv,一个用纯ANSI C89编写的小而简单的库。

答案 1 :(得分:0)

滚动您自己的strtok并检查其中的引号。 (你的示例字符串不包含任何';'内部引号,所以也许我误解了整个问题:)

无论如何,这是我对strtok的粗略版本的看法,其工作方式类似,只是它只接受一个单一的令牌字符而不是字符串(但如果需要,可以轻松添加)并且它会进行以下操作:解析以下内容:

  • "开头的字符串与结束"
  • 匹配
  • '开头的字符串与结束'
  • 匹配
  • 任何个别角色都可以通过预先\
  • 进行转义

不匹配的"'只会匹配字符串末尾的所有内容。

#include <stdio.h>

char *get_token (char *input_str, char separator)
{
    static char *last_pos;

    if (input_str)
        last_pos = input_str;
    else
        input_str = last_pos;

    if (last_pos && *last_pos)
    {
        while (*last_pos)
        {
            if (*last_pos == separator)
            {
                *last_pos = 0;
                last_pos++;
                return input_str;
            }
            if (*last_pos == '\"')
            {
                last_pos++;
                while (*last_pos && *last_pos != '\"')
                    last_pos++;
            } else
            if (*last_pos == '\'')
            {
                last_pos++;
                while (*last_pos && *last_pos != '\'')
                    last_pos++;
            } else
            if (*last_pos == '\\' && last_pos[1])
            {
                last_pos++;
            }
            last_pos++;
        }
        return input_str;
    }
    return NULL;
}

void main (void)
{
    char str[] = "\"./test; script\";ls -a\\;b -o;mkdir \"te>st\";ls > 'some;file.txt'";
    char *cmdSplitToken = get_token (str, ';');

    while (cmdSplitToken != NULL)
    {
        printf("arg %s\n", cmdSplitToken);
        cmdSplitToken = get_token (NULL, ';');
    }
}

这只会修复命令解析的前半部分。第二部分可以使用相同的例程处理,或者 - 据我所知 - 使用沼泽标准strtok

顺便说一句,我的例程中的static char使不可重入 - 使用交替字符串。 (可能你已经知道了,因为你也在自己的代码中避免使用它。)