c - Strtok 没有按预期返回,我使用它是否错误?

标签 c split c-strings strtok function-definition

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// fiter string to the first |
char* filterstringfirst(char* command, int i){
    char *tok = command;
    int x = 0;
    while ((tok = strtok(tok, "|")) != NULL && x <= i)
    {
        if( x == i){
            return tok;
        }
        x++;
        printf(" ===  Parsed: --%s-- ===\n", tok);
        tok = NULL;
    }
    return tok;
        
}


int main () {
    char command[]  = "ls -a | sort -h | grep h | wc -l";
    
    char command2[]  = "ls -a | sort -h | grep h | wc -l";
    char* temp = command;

    char* x =  filterstringfirst(temp, 0);
    printf("%s\n",x);
    char* temp2 = command;

    char* x2 =  filterstringfirst(temp2, 1);
    printf("%s\n",x2);
    
    
   
    temp = command;
    

   return 0;
}

我创建了这个函数,它应该只返回字符串的一部分。原始字符串应类似于“ls -l | grep temp | sort”。

这个想法是用字符串和数字调用它,并返回该段。例如。 0 -> “ls -l”

现在,我第一次调用它时,它就可以工作,但再次调用它似乎会中断并以段错误结束。

char command[]  = "ls -a | sort -h | grep h | wc -l";
char* temp = command;

char* x =  filterstringfirst(temp, 0);
printf("%s\n",x);
char* temp2 = command;

char* x2 =  filterstringfirst(temp2, 1);
printf("%s\n",x2);`

这是我的测试代码

输出:

ls -a  
===  Parsed: --ls -a -- === 
[1]    1126 segmentation fault  ./templ
 ➜  Current gcc -o templ templ.c
 ➜  Current ./templ ls -a  
===  Parsed: --ls -a -- === [1]   
 1136 segmentation fault  ./templ

编辑:更新为也有 main (基于评论)

最佳答案

strtok 具有破坏性 - 它通过将分隔符替换为空字节来修改传入的缓冲区。

之后

char* x =  filterstringfirst(temp, 0);

命令实际上将是“ls -a”

如果您想在此处使用 strtok,您需要:

  • 在包装函数中模仿 strtok,通过传递 NULL 以及后续调用中的起始位置,或者

  • 在使用字符串之前复制该字符串,并返回 token 的副本。

第二个示例,没有错误处理:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *get_token_at(char *command, size_t n) {
    size_t position = 0;
    char *copy = strdup(command);
    char *token = strtok(copy, "|");
    char *output = NULL;

    while (token && position < n) {
        token = strtok(NULL, "|");
        position++;
    }

    if (token && position == n)
        output = strdup(token);

    free(copy);

    return output;
}

int main(void) {
    char command[]  = "ls -a | sort -h | grep h | wc -l";

    char *x = get_token_at(command, 0);
    puts(x);
    free(x);

    x = get_token_at(command, 1);
    puts(x);
    free(x);
}

标准输出:

ls -a 
 sort -h

(请注意这些标记中的空格。)

关于c - Strtok 没有按预期返回,我使用它是否错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71652705/

相关文章:

android - 使用动态库交叉编译 C 代码时出错

C - 使用双指针动态内存分配

php - 在非字母数字字符以及数字和非数字之间的位置上拆分字符串

c++ - 对混合(空和非空)cstring 数组进行排序

c - 有没有办法限制用户只能输入变量的数值?

c - 父级不从管道读取

python - 从数据框中的字符串中提取子字符串

Java - 混淆字母

c++ - const char * 在循环期间改变值

将结构体中的字符数组与用户输入的字符数组进行比较