strtok只返回一个令牌

时间:2011-12-09 19:09:34

标签: c delimiter strtok

我正在编写一个简单的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 :(得分:5)

您无法混合多个strtok来电。这是正在发生的事情:

  • 您开始拆分input,以便 strtok注意并在内部存储内容
  • 您可以暂停分割input
    • 您开始拆分copy,所以strtok请注意,从而破坏以前的信息
  • 此时strtok只知道copy业务,并且对原始input一无所知。

主要问题是 strtok不知道你同时做了两件事。从它的角度来看,你只需在完成第一个字符串之前就开始处理不同的字符串。


可能的解决方案:

  • 如果有,请使用strtok_r。它不是标准的C(但它是标准的POSIX)。 r代表可重入
  • 使用您自己的分割功能(strchr / looping等)
  • 更改您的程序逻辑,以便在完成copy
  • 之前无需拆分input

关于最后一点:

  • 保留一个char *数组并填充strtok而不暂停拆分子标记。所以每个元素应该是一个不同的命令
  • 完成";"拆分后,开始处理每个数组元素

答案 1 :(得分:0)

这个怎么样:

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, ";");
  }
}