【问题标题】:Weird output from strtokstrtok 的奇怪输出
【发布时间】:2017-07-31 09:37:50
【问题描述】:

我在处理 char* 数组中的 char* 时遇到了一些问题,并将其用作参考:Splitting C char array into words

所以我想要做的是读取 char 数组并用空格分隔符将它们拆分,这样我就可以用它做一些事情了。例如,如果我的 char* 中的第一个标记是“Dog”,我会将其发送到处理狗的不同函数。我的问题是我得到了一个奇怪的输出。

例如:

输入:*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);
  }

有什么建议吗?我是 C 的新手,所以如果我做了一些愚蠢的事情,请多多包涵。谢谢。

【问题讨论】:

  • 我不明白:如果你不保存你得到的指针列表,为什么要calloc(3)它们然后释放......为什么使用p_args数组,分配给它,然后终于free(3)了吗?
  • 我将 p_args 传递到不同的函数中,我只是还没有添加该代码并抢先放入免费的。我只是想让 strtok 先正常工作。
  • 哦.... 抱歉当时的评论。
  • np 我应该澄清一下

标签: c arrays


【解决方案1】:

在你的情况下,

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.]

第一步工作正常,因为您使用 space 作为分隔符,并通过在 Dog 末尾放置 \0 来修改字符串。

这意味着 下一个 尝试(使用错误的分隔符)将使用来自{D,o,g} 的字母之一进行拆分。该集合的第一个匹配字母是appointment 中的o,这就是您看到needs a vet app 的原因。第三次尝试找到 none 个候选字母,因此您只需取回字符串的其余部分,intment.

【讨论】:

  • 太棒了,我不知道我是怎么犯这个错误的 :( 谢谢先生!
【解决方案2】:

token = strtok(NULL, cmd); 应该是token = strtok(NULL, " ");

第二个参数是delimiter


  1. http://man7.org/linux/man-pages/man3/strtok.3.html

【讨论】:

  • 哦,哇,我真是太愚蠢了。我只是假设这是别的东西,因为我得到了类似的输出。谢谢。知道为什么它仍然会拍出类似的东西吗?
猜你喜欢
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 2015-02-18
  • 2011-06-14
  • 2013-06-04
相关资源
最近更新 更多