我正在尝试拆分字符串并打印令牌。
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
问题是什么?
答案 0 :(得分:7)
好吧,我认为这是一个无关的问题,但我现在认为这是你所看到的问题。
重要的是要记住C字符串比它们包含的字符多1个字符。这是终止NUL字符(\0
),标记文本的结尾。
所以KLA1513
实际上是8个字符(KLA1513\0
)。此外,因为你没有修剪空格,它是9个字符! _KLA1513\0
(_是空格)。
这意味着您在第二个strcpy
中占用内存,导致未定义的行为,这将是您最糟糕的噩梦。
当你打印它时,谁知道程序处于什么状态。也许你覆盖的内存是print
调用的一部分,或者它可能被重写,现在var2
没有被终止
只需使var2
更大(此处有9个字符就足够了),将来使用安全表单(例如strncpy
)。像这样的错误是黑客通常设法破坏系统的方式。
答案 1 :(得分:2)
试试这个:
#include <stdio.h>
#include <string.h>
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字符串。