【问题标题】:strtok gives me only the first slicestrtok 只给了我第一片
【发布时间】:2014-08-30 15:14:39
【问题描述】:

这是我用 C 编写的第一个项目,我正在尝试将 C 字符串拆分为“单词”。

以下几行用于测试并正常工作:

Serial.println("SliceTest2");
  char *ptr;
  char delimiter[] = " ,";
  ptr = strtok(packetBuffer, delimiter);
  Serial.println(ptr);
  ptr = strtok(NULL, delimiter);
  Serial.println(ptr);
  ptr = strtok(NULL, delimiter);
  Serial.println(ptr);
  ptr = strtok(NULL, delimiter);
  Serial.println(ptr);
  ptr = strtok(NULL, delimiter);
  Serial.println(ptr);
  ptr = strtok(NULL, delimiter);
  Serial.println(ptr);

packetBuffer 包含“a b c d e f g h”,这是输出(正确):

SliceTest2
a
b
c
d
e
f

现在,当我使用以下行时:

char *sliceStr(char fullString[]){
  char *ptr;
  ptr = strtok(packetBuffer, " ");
  ptr = strtok(NULL, "\n\t ");
  return("%s", ptr);
}

并调用它们(在 packetBuffer "a b c d e f g h" 中使用相同的内容):

Serial.println(sliceStr(packetBuffer));

应该打印

b

但什么都不做。

顺便说一句,这是一个 arduino 项目,但是一个特定于 C 的问题。

lg, couka

【问题讨论】:

  • 不应该是char *sliceStr(char *packetBuffer){吗?
  • ptr = strtok(packetBuffer, " "); -->> ptr = strtok(fullString, " ");
  • 顺便说一下,我不认为return("%s", ptr); 像你认为的那样工作。
  • return("%s", ptr); - 这是什么意思?

标签: c string strtok


【解决方案1】:

这不是纯 C。 Serial.println("foo");这是一个类的方法。可能您正在使用 C/C++ 派生语言在 Arduino 或类似语言上进行编程。

printf("%s", ptr); 将用地址ptr 处的字符串替换%s - 但仅仅是因为它是一个函数

return 是一个返回值的关键字,在这种情况下,您需要指针 ptr

return("%s", ptr); 在 C 中没有意义。

另请注意:返回的char* 指针必须指向有效的 c 字符串,例如在调用函数之前声明的字符串。注意不要返回指向函数内部声明的变量的指针,因为它们是本地的,并且在函数结束时消失。

长话短说,试试看:return ptr;

如果它不起作用并需要进一步帮助,请具体说明您使用的是什么语言和平台

编辑: return("%s", ptr); 错误,但仍然有效。

但是,当您要标记的参数实际上是 fullString 时,您使用了全局变量 packetBuffer

此示例代码将按您的预期工作并打印b。 我在示例中使用了参数的分配副本,因为 strtok 在标记化期间需要可写内存来放置临时零(字符串结尾)。

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

char *sliceStr(char *packetBuffer){
  char *ptr;
  ptr = strtok(packetBuffer, " ");
  ptr = strtok(NULL, "\n\t ");
  return("%s", ptr);
}

int main() {
    char *str = strdup("a b c d etc");
    printf("%s\n", sliceStr(str));
}

【讨论】:

  • return("%s", ptr) 是有效的 C 代码。但确实没有意义。
  • 安德烈 T 是对的。在c 中,语句"%s", ptr 是有效的,从左到右计算,最右边的值是整个语句的返回值。因此,return("%s", ptr) 语句将返回 ptr 的计算结果。
  • Serial.println("foo"); 也是有效的 C,如果 Serial 是具有名为 println 的指向函数的成员的 struct 的名称。
  • 我很欣赏这里的所有学究,虽然我看不出他们对这个话题有什么帮助。正如 OP 所说他是一个初学者,我怀疑他的意图是发起一场混淆 C 闪电战。
  • 我看不出在你的回答中错误地告诉他他没有用 C 编程会更有帮助。如果您认为他不在乎,那为什么还要提起这些?
【解决方案2】:

感谢您的建议。

混合packetBufferfullString 是愚蠢的,但并没有导致问题,因为直到现在它总是具有相同的内容。

return("%s", ptr) 还没有结束,没有任何意义,但这里没有问题。

我还没有设法让它与纯 C 一起工作,所以从现在开始我将使用 C++ 及其String-class。不想,不过还好……

不管怎样,问题似乎出在ptr = strtok(NULL, " ");这一行。

 ptr = strtok(fullString, " ");

按预期给我第一个词,但用NULL 重复它永远不起作用。

lg, couka

【讨论】:

  • 老兄复制/粘贴我的答案中的代码并编译并运行它你会看到它工作我自己测试过。
  • 我知道你修复了你的代码,但我不知道怎么做。根据缓冲区的来源以及函数与外部变量之间的关系,可能会产生许多副作用。如果你坚持你的代码是正确的,但它不起作用,只需将整个源代码粘贴在这里,我会看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 2021-04-14
相关资源
最近更新 更多