首页 文章

strtok只返回一个令牌

提问于
浏览
1

我正在编写一个简单的shell,它接受一些标准命令,比如C中的cd和ls . 我正在尝试实现一个用户可以输入“;”的功能 . 在命令之间,以便可以在同一行上写入一堆命令并单独执行 . 因此,如果我输入“cd Desktop; ls”,shell应该cd到Desktop并打印目录中的内容 . 问题是它只执行第一个命令 . 这是我的主要方法:

char input[1024];

while(1)
{
    printf("%s ", prompt);
    fgets(input, 1024, stdin);

    char delims[] = ";";
    char *result = NULL;
    result = strtok( input, delims );

    while( result != NULL )
    {
        printf("%s\n", result);

        char * copy = malloc(strlen(result) + 1); //Create a copy of the input token
        strcpy(copy, result);

        format(copy);

        if(programs)
        {
            handle();
            cleanup(programs);
            programs = NULL;
        }
        free(copy);
        result = strtok( NULL, delims );
        cmdno++;
    }
}

首先,我尝试将输入分解为基于“;”的标记 . 然后将令牌提供给format()方法,如下所示:

int format(char input[])
{
    input = strtok(input, "\n");
    ...
}

我知道strtok会对原始字符串进行更改,这就是为什么我在将令牌传递给格式之前先创建令牌的副本 . 我正在做的正确吗?

2 回答

  • 0

    你不能混合多个 strtok 电话 . 在这里_1791237发生了什么:

    • 你开始拆分 input 所以 strtok takes note and stores stuff internally

    • 你从分裂 input 休息一下

    • 你开始拆分 copy 所以再次 strtok 请注意, thereby destroying the previous info

    • 此时 strtok 只知道 copy 业务,并且对原始 input 一无所知 .

    主要问题是 strtok doesn't know that you're doing two things at the same time . 从它的角度来看,你只需在完成第一个字符串之前就开始处理不同的字符串 .


    可能的解决方案:

    • 如果有,请使用strtok_r . 它不是标准的C(但它是标准的POSIX) . r 代表可重入

    • 使用你自己的分裂函数(strchr / looping等)

    • Change your program logic such that you don't need to split copy before finishing with input

    关于最后一点:

    • 保留一个 char * 数组并用 strtok 填充它而不暂停拆分子标记 . 所以每个元素应该是不同的命令

    • 完成 ";" 拆分后,开始处理每个数组元素

  • 5

    那这个呢:

    char line[1024];
    char *token;
    while (1) {
      printf("$ ");
      fgets(line, 1000, stdin);
      token = strtok(line, ";");
      while (token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, ";");
      }
    }
    

相关问题