我在处理char*数组中的char*时遇到了一些问题,并将其用作参考:Splitting C char array into words
所以我要做的是读入char数组,并用空格分隔符将它们分开,这样我就可以用它做一些事情。例如,如果char*中的第一个标记是“Dog”,我会将它发送到处理dogs的不同函数。我的问题是我得到了一个奇怪的结果。
例如:
输入:*cmd=“狗需要兽医预约。”
输出:(来自打印报表)“不需要兽医申请。”
我用valgrind检查过内存泄漏,没有任何错误。

void parseCmd(char* cmd){ //passing in an individual char* from a char**
  char** p_args = calloc(100, sizeof(char*));
  int i = 0;
  char* token;
  token = strtok(cmd, " ");
  while (token != NULL){
    p_args[i++] = token;
    printf("%s",token); //trying to debug
    token = strtok(NULL, cmd);
  }
  free(p_args);
  }

有什么建议吗?我是新来的,所以如果我做了傻事,请容忍我。谢谢您。

最佳答案

对你来说,

token = strtok(NULL, cmd);

不是你应该做的。相反,你需要:
token = strtok(NULL, " ");

根据ISO标准:
char *strtok(char * restrict s1, const char * restrict s2);
strtok函数的一系列调用将s1指向的字符串断开为一系列标记,每个标记由s2指向的字符串中的一个字符分隔。
第一次调用和随后的调用之间的唯一区别(根据本例,假设您希望使用相同的分隔符)应该是使用NULL作为输入字符串,而不是实际字符串。通过在后续调用中将输入字符串用作分隔符列表,可以更改行为。
如果您尝试以下代码,就可以确切地看到发生了什么:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void parseCmd(char* cmd) {
    char* token = strtok(cmd, " ");
    while (token != NULL) {
        printf("[%s] [%s]\n", cmd, token);
        token = strtok(NULL, cmd);
    }
}

int main(void) {
    char x[] = "Dog needs a vet appointment.";
    parseCmd(x);
    return 0;
}

哪个输出(第一列将是使用下一个迭代的搜索字符串,第二列是此迭代的结果):
[Dog] [Dog]
[Dog] [needs a vet app]
[Dog] [intment.]

第一步工作得很好,因为您使用空格作为分隔符,并且它通过在\0的末尾放置Dog来修改字符串。
这意味着下一次尝试(使用错误的标枪)将使用{D,o,g}中的一个字母进行拆分。该集合的第一个匹配字母是o中的appointment,这就是您看到needs a vet app的原因。第三次尝试没有找到任何候选字母,因此您只需返回字符串的其余部分,intment.

关于c - strtok的输出奇怪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45406279/

10-11 22:10
查看更多