C String拆分并打印令牌。

我正在尝试拆分字符串并打印令牌。

int main() { char line[255] = "182930101223, KLA1513"; char val1[16]; char val2[7]; strcpy(val1, strtok(line, ",")); strcpy(val2, strtok(NULL, ",")); printf("%s|%s\n", val1, val2); return 0; } 

当我打印我得到

  3| KLA1513 

代替

182930101223 | KLA1513

有什么问题?

好吧,我认为这是一个无关的问题,但我现在认为这是你所看到的问题。

重要的是要记住,C字符串比它们包含的字符多1个字符。 这是终止NUL字符( \0 ),并标记文本的结尾。

所以KLA1513实际上是8个字符( KLA1513\0 )。 此外,因为你没有修剪空格,它是9个字符! _KLA1513\0 (_是空格)。

这意味着你在第二次strcpy超出了内存,导致未定义的行为 ,(你会发现)是你最糟糕的噩梦。

当你打印它时,谁知道程序处于什么状态。也许你覆盖的内存是print调用的一部分,或者它可能被重写,现在var2没有终止。

只需使var2更大(这里有9个字符就足够了),将来使用安全表格(例如strncpy )。 像这样的错误是黑客通常设法破坏系统的方式。

试试这个:

 #include  #include  int main() { char line[] = "182930101223, KLA1513"; char* val1; char* val2; val1 = strtok(line, ","); val2 = strtok(NULL, ","); printf("%s|%s\n", val1, val2); return 0; } 

没有必要strcpy()标记,你可以只使用char* ; strtok()将在找到的每个标记的末尾添加一个结束\0

它也更安全,因为您不需要事先知道令牌的大小; 和令牌的大小是问题。 如果您确实需要将令牌放在自己的内存中,则可以将其复制到足够大小的字符串中。

请注意,我们不能这样做:

 char* line = "182930101223, KLA1513"; 

因为strtok()修改了字符串,并且不允许修改文字C字符串。