我目前在C语言中有一个名为'json'的字符串“ {” method“:” emptyFood“,” params“:” 08:00 09:00 10:00“}”
,然后尝试将时间提取到3个不同的变量中。
for(int i = 0; i<5; i++)
{
ts1[i] = json[i+32];
}
for(int j = 0; j<5; j++)
{
ts2[j] = json[j+38];
}
for (int k = 0; k<5; k++)
{
ts3[k] = json[k+44];
}
printf("time1 = %s\n", ts1);
printf("time2 = %s\n", ts2);
printf("time3 = %s\n", ts3);
如果同时打印所有内容,则会得到类似这样的奇怪输出
time1 = 08:009:010:00
time2 = 09:010:00
time3 = 10:00
但是,如果我一张一张地打印它们,它将为每个打印语句打印出正确的时间。
我在做什么错了?
答案 0 :(得分:0)
C中的字符串以空值结尾。这意味着字符串以空字节结尾。 (字符串中的字节的类型为char
。)将子字符串的字节复制到新的字节数组时,就是在复制字符串的“有用”内容,但要获得完整的字符串,您还需要编写空终止符。例如:
for(int i = 0; i<5; i++)
{
ts1[i] = json[i+32];
}
ts1[5] = 0;
(不要混淆空字节0
和数字'\0'
,也可以将其写入'0'
。)
一种更惯用的写法是
memcpy(ts1, json + 32, 5);
ts1[5] = 0;
设计更好的复制子字符串的函数是strlcpy
,但不幸的是它不是标准C的一部分,因此许多平台都没有。请注意,strncpy
做得不好,因为在您的情况下它不会写空字节。
请注意,您需要6个字节来存储5个字节的字符串,即必须声明char ts1[6]
或char *ts1 = malloc(6)
(或更大的数字)。
一一打印字符串似乎有效的原因是在内存中的字符串之后必须立即有一个空字节。这只是一个巧合,如果从不同的地方调用该函数,如果该函数之前的代码已处理不同的数据,如果使用不同的编译器进行编译等,则可能不会发生。给定输出,您可以获得这三个变量,那么必须发生的情况是编译器碰巧将ts1
,ts2
和ts3
放在内存中,而其他事情以空字节开始。因此,当您尝试打印ts1
时,该地址处的字符串越过了ts1
,ts2
和ts3
,最终在该空字节处停止。空字节只是运气,或者是运气不好,因为它隐藏了missing null terminator的错误。