Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将字符串拆分为标记,忽略用“"&引用;_C_String_Substring_Strtok - Fatal编程技术网

C 将字符串拆分为标记,忽略用“"&引用;

C 将字符串拆分为标记,忽略用“"&引用;,c,string,substring,strtok,C,String,Substring,Strtok,我正在创建自己的命令行解析器,并使用strok()和\t的分隔符(空格)拆分子字符串 但是,如果子字符串包装在\“中,则不应拆分其内容是有意义的,因为子字符串需要自由包含空格字符 有什么已知的函数或简单的方法可以做到这一点吗?我非常懒得用优雅的方式来做,所以我只是用懒散的方式来做。 下面是最丑陋的功能: char* foo (char* str) { static char* p; int subcontainer = 0; int escBackslash = 0;

我正在创建自己的命令行解析器,并使用
strok()
\t
的分隔符(空格)拆分子字符串

但是,如果子字符串包装在
\“
中,则不应拆分其内容是有意义的,因为子字符串需要自由包含空格字符


有什么已知的函数或简单的方法可以做到这一点吗?

我非常懒得用优雅的方式来做,所以我只是用懒散的方式来做。 下面是最丑陋的功能:

char* foo (char* str)
{
    static char* p;
    int subcontainer = 0;
    int escBackslash = 0;
    int i = 0;
    if(p == NULL)
    {
        p = str;
        if(*p == '\\')
            escBackslash = 1;
    }
    char* offset = NULL;
    for(offset = p; *p != '\0'; p++)
    {
        if(*p == '\\')
        {
            escBackslash = 1;
            i = 1;
            continue;
        }
        if(*p == '"' && escBackslash == 0)
        {
            if(subcontainer < 1)
            {
                subcontainer = 1;
                offset++;
            } else subcontainer = -1;
        }
        if(isspace(*p) && subcontainer < 1)
        {
            if(i) *(p - 3) = '"';
            if(i) *(p - 2) = '\0';
            *(p-(-subcontainer)) = '\0';
            p++;
            return offset + i;
        }
        if(*(p+1) == '\0')
        {
            if(i) *(p - 2) = '"';
            if(i) *(p - 1) = '\0';
            if(subcontainer == -1) *p = '\0';
            p++;
            return offset + i;
        }
        escBackslash = 0;
    }
    return NULL;
}

没有标准的库函数来实现这一点。您可以查看Posix
wordexp
函数(如果平台上有),但在使用它时要非常小心,因为它可以执行任意shell命令(使用
WRDE_NOCMD
标志帮助),并且没有定义(可能不安全)如果像
这样的特殊字符,我已经在命令行解析器(实际上更像是我程序的实时解释器脚本工具)上取得了进展,我很累,我宁愿不使用这个函数,因为它可能存在于我的平台上(Windows但cygwin),这是一个非常慢的函数,可能根本没有优化,我有点懒得尝试学习如何使用这个函数,因为它看起来相当复杂。我并不是真的推荐使用它,tbh,这就是为什么我没有给出答案。如果我要回答,我会坚持“没有有用的标准函数,但这对于学习flex来说是一个不错的入门练习。”:-)不过,了解它可能会很有用。(在Windows上,实际上有一个更有用的函数。Windows shell不使用word拆分命令行,因此需要使用库函数来完成。编辑:
命令行到argvw
)@rici刚刚看到了这个功能,很好的捕获。实际上可能特别适用于打算在Windows下运行的应用程序。因为我使用cygwin,而不是MSV,所以我的目标是不要将我的应用程序窗口化太多,以便于移植。也就是说,也许我可以得到
strtok
实现并修改它它的行为,也许这接近于一个简单的解决方案它很容易解析引号。问题是反斜杠的正确处理,特别是在人们经常使用反斜杠作为目录分隔符的windows上。但它并不太复杂。我会使用状态机而不是strok,因为strok实际上不是很快也不是很灵活祝你好运。
int main()
{
    char* str = strdup("\"\\\"test\\\"\" + \"Command 2\" \"Command2\" function \"\\\"nice\\\"\"");

    printf("[%s]\n", str);

    char* str1 = foo(str);

    while(str1 != NULL)
    {
        printf("str[%s]\n", str1);

        str1 = foo(NULL);
    }

    free(str);
    return 0;
}