c操作指向char数组的指针,混淆

c manipulating pointer to char array, confusion

本文关键字:指针 混淆 数组 char 操作      更新时间:2023-10-16

我已经为arduino pro mini编写了操作指向char数组的指针的代码,用于格式化NMEA RMC语句中的时间和日期,比如:

char *UTC = "120435";
char *DATE = "050117";
char TIME[9];
char *ptr = TIME;
char *fieldPtr = UTC;
for (int a = 0; a < 8; a++) {
*ptr++ = *fieldPtr++;
if (a == 1 || a == 3) {
*ptr = ':';
ptr++;
}
}
*ptr = '';
Serial.print("TIME: ");   
Serial.println(TIME);     //output: "12:04:35"  //-OK
char date[9];
ptr = date;
fieldPtr = DATE;
for (int a = 0; a < 8; a++) {
*ptr++ = *fieldPtr++;
if (a == 1 || a == 3) {
*ptr = '.';
ptr++;
}
}
*ptr = '';
Serial.print("TIME: ");
Serial.println(TIME);        //output: "d"  //whatever follows DATE
Serial.print("date: ");
Serial.println(date);        //output: "05.01.17"  //-OK

第二轮中TIME的输出似乎是内存中DATE后面的某个字符。

有人能帮我解释一下发生了什么事吗?

您在数组边界之外进行读写操作。

看看这个部分:

for (int a = 0; a < 8; a++) {
*ptr++ = *fieldPtr++;

在第一个循环中,您可以通过fieldPtr访问UTC。在内存中,UTC看起来像:

'1' '2' '0' '4' '3' '5' ''

所以当a0时,你读1,当a1时,你看2,以此类推

'1' '2' '0' '4' '3' '5' '' 
^   ^   ^   ^   ^   ^   ^   ^
a=0 a=1 a=2 a=3 a=4 a=5 a=6 a=7

对于a=7,您在数组外读取,这是非法的(即未定义的bahvio)。

对于写作部分来说,它或多或少是一样的。除了您有两个额外的ptr增量。所以写作是:

TIME[0] TIME[1] TIME[2] TIME[3] TIME[4] TIME[5] TIME[6] TIME[7] TIME[8]
^       ^       ^       ^       ^       ^       ^       ^       ^       ^
a=0     a=1     a=1     a=2     a=3     a=3     a=4     a=5     a=6     a=7

再说一遍,当a=7时,你在TIME之外写作。事实上,你在循环后再写一次:*ptr = '';

所以所有这些都是"未定义的行为"。

当你有未定义的行为时,从语言的角度来看,讨论正在发生的事情是没有意义的

但是,您可以分析您的特定系统上发生了什么。这可能是因为,当您在第二个循环中写入DATE并在DATE数组之外写入时,写入的数据可能最终会在TIME中,从而破坏原始值,从而导致打印错误。请再次注意,这将是特定于系统的。在我的系统中,尽管存在未定义的行为,但您的代码仍会产生预期的输出。

要解决您的问题,请参阅@PaulOgilvie 的答案

由于您处理的是固定大小的小输入字符串,因此避免所有指针内容的替代解决方案可能是:

char *UTC = "120435";
char TIME[9];
if (strlen(UTC) == 6)
{
sprintf(TIME, "%c%c:%c%c:%c%c", UTC[0], UTC[1], UTC[2], UTC[3], UTC[4], UTC[5]);
printf("%sn", TIME);
}
else
{
printf("wrong formatn");
// .... add error handling here ....
}

循环的迭代次数太多。它必须复制长度为6的输入字符串,并插入另外两个字符。但这不会改变输入长度。将循环更改为:

for (int a = 0; a < 6; a++) {
...