3

我对 C 编程很陌生,目前正在努力使用 strtok。我想使用以下代码将一个字符串拆分为两个字符串(字符串例如“Bat1:185”,分隔符是冒号):

char batName[13];
char batVoltage[3];
char *result = NULL;

result = strtok(pStringToSplit, pDelimiter);
strcpy(batName, result);

result = strtok(NULL, pDelimiter);
strcpy(batVoltage, result);

在第一次 strtok 调用之后 batName 包含预期的值(“Bat1”),但在第二个 strtok batName 为空之后,batVoltage 包含正确的值“185”。

我知道这段代码很弱,但目前我只是想了解 strtok 的基础知识。我已经花了很多时间寻找解决方案,但找不到任何解决方案。

非常感谢彼得的任何提示

4

4 回答 4

2

该值185以 nul (\0) 字符结尾,并且实际占用 4 个字符的空间。你写在缓冲区之外,似乎用字符串终止符nul覆盖了第一个字符。batName

严格来说,覆盖缓冲区是未定义的行为,因此该代码实际上可以以任何方式运行,具体取决于编译器。

于 2013-08-06T10:51:19.067 回答
1

您的代码中有缓冲区溢出。请记住,目标字符串数组需要一个额外的字符作为终止'\0'字符。这意味着当您获得第二个子字符串时,您会覆盖batVoltage数组并显然进入batName数组。

batVoltage将数组的大小增加一,它应该可以正常工作。

于 2013-08-06T10:51:40.563 回答
1

正如 Joachim 指出的那样,您有一个电压缓冲区溢出,因为它的三个字符185,目标需要一个额外的空间用于 NULL ( \0)。

所以,

int main ()
{
char batName[13]; // Battery Identifier must be <=12, 1 for NULL
char batVoltage[3+1]; //Increase size, not just 4, but max digits of volatage+1
char *result = NULL;

char pStringToSplit[] ="Bat1:185";
const char *pDelimiter=":";

result = strtok(pStringToSplit, pDelimiter);
strcpy(batName, result);

result = strtok(NULL, pDelimiter);
strcpy(batVoltage, result);

printf("Battery :%s  Voltage:%s ",batName,batVoltage);

  return 0;
}
于 2013-08-06T11:05:18.583 回答
0

正如Joachim PileborgJoachim Isaksson回答的那样,你会打到Buffer Overflow这里。如果您解决此问题并根据您的字符串(如果是这样)继续前进,Bat1:185:Bat2:186:Bat3:187您可以做一些数学知识来标记这个字符串。

After the first strtok call batName contains the value ("Bat1") as expected, but after the second strtok batName is empty, batVoltage contains the correct value "185".

在这里,您可以轻松地检查在您收到的每个奇数电话和您将收到Bat*的每个偶数电话之后18*

我希望这也能帮助你。

于 2013-08-06T11:07:14.493 回答