我对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的基础知识。我已经花了很多时间寻找解决方案,但找不到任何解决方案。
非常感谢任何提示 彼得
答案 0 :(得分:2)
值185
以nul(\ 0)字符终止,实际占用4个字符的空格。你的nul
写在缓冲区之外,似乎用字符串终止符覆盖batName
中的第一个字符。
严格来说,覆盖缓冲区是未定义的行为,因此这段代码可能会以任何方式运行,具体取决于编译器。
答案 1 :(得分:1)
您的代码中有缓冲区溢出。请记住,目标字符串数组需要额外的字符来终止'\0'
字符。这意味着,当您获得第二个子字符串时,您会覆盖batVoltage
数组,并且显然会覆盖batName
数组。
将batVoltage
数组的大小增加1,它应该可以正常工作。
答案 2 :(得分: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;
}
答案 3 :(得分:0)
当Joachim Pileborg和Joachim 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*
。
我希望这对你也有所帮助。