【问题标题】:Unexpected behavior when printing out char array打印出 char 数组时的意外行为
【发布时间】:2017-06-03 20:39:29
【问题描述】:

我目前正在尝试通过在特定点打印某些变量的值来通过 UART 调试我的程序。我的问题是打印两个字符数组。我打印它们的顺序似乎会影响它是否打印。数组的声明位于头文件的结构中,如下所示-

//header file
typedef struct
{
  char latitude[10]; 
  char longitude[11];
}NMEA_RMC_t;

NMEA_RMC_t rmc;

从输入解析数据后,char 数组在另一个函数中进行操作。尽管程序中的其他地方存在中断,但它们不会通过中断更新。在主代码中,如果我按如下方式打印它们-

//main program loop
printf("lat: %s \t long: %s \n", rmc.latitude, rmc.longitude);

到终端的输出是这个-

纬度:+50.71735 经度:

而如果我像这样以不同的顺序打印它们-

printf("long: %s \t lat: %s \n", rmc.longitude, rmc.latitude);

我得到了这个输出。

长:-001.39118 纬度:

如果我将打印分成两个单独的 printf 语句,则只有第一个 print 语句正确打印 char 数组。我以前不必在这里寻求帮助,但这让我困了一个星期。任何帮助将不胜感激!干杯。

编辑

写入数组的程序部分就是这个。纬度和经度数组基本相同。

/* now we are in first char of latitude */

/* copy latitude chars */
strlcpy ((char*)lat, (const char*)ptr_to_comma, 10 );/*copies most size-1, null terminated*/   //changed 11 to 10

/* default latitude presentation is ddmm.mmmmm 
    we need to change it to dd.mmmmmmm 
*/
unsigned char ind;
for (ind=0; ind<9; ind++)
{
    if (*ptr_to_comma == '.')
    {
        ptr_to_comma++;//step over '.'
    }
    if ( ind==2 )
    {
        lat[ind++]='.';
    }
    lat[ind] = *ptr_to_comma;
    ptr_to_comma++;
}
lat[10] = '\0'; //terminate
/* now lat == dd.mmmmmmm */

ptr_to_comma++; /*step over comma to the NS-indicator*/

/*catch NorthSouth-indicator and step*/
if ( *ptr_to_comma == 'N'){ /*if we are in the North*/
    sign = '+';
    rmc.ns_indicator = 'N';
} else if ( *ptr_to_comma == 'S'){ /*else we are in the South*/
    sign = '-';
    rmc.ns_indicator = 'S';
}
ptr_to_comma++;//step over NS-indicator
ptr_to_comma++;//step over comma to the longitude field

/* dd.mmmmmmm to dd.ddddddd */

_convert_minutes( (unsigned char*) lat+3 );

/* copy latitude with sign to the rmc-struct */
rmc.latitude[0] = sign;
strcpy ( (char*)rmc.latitude+1, (const char*)lat); 
rmc.latitude[10]='\0';

本质上是从传入的数据流中解析信息。

【问题讨论】:

  • 你如何初始化你的数组?
  • 我怀疑它可能与 UART 接收器有关。也许字符串的其余部分尚未从较低层读取。 Rx 缓冲区大小是多少?您确定您已从 UART 发送器读取所有字节吗?
  • 即使我在两个单独的 printf 语句中打印两个数组,第二个也永远无法正常工作 - 无论哪个是第一个。我尝试打印一些大文本,所有这些都很好。谢谢你的建议。
  • @GeorgeStokes,看看你的更新。 rmc.latitude[10]='\0' 实际上把 '\0' 放到了经度[0]。试试rmc.latitude[9]='\0'

标签: c avr avr-gcc


【解决方案1】:

要使%s 正常工作,char 数组必须有一个 NUL 终止符 \0,它表示字符串的结尾。

如果你不为此留出空间,你的程序的行为是未定义的

您需要自己初始化数组 - 不要依赖编译器来完成。

取出您的调试器并在printf 处检查与rmc 关联的内存。

【讨论】:

  • 你会推荐这样的东西吗? rmc.latitude[(sizeof(rmc.latitude)-1)] = '\0';
  • 为了安全起见,我个人会将整个数组归零,至少一开始是这样,
【解决方案2】:

您用于转换字符串并将它们放入结构的代码无意中在rmc.longitude 的开头放置了一个“\0”字符。然后代码继续用正确的值填充数组的其余部分,但 printf() 函数将 rmc.longitude 视为零长度字符串并忽略后面的内容。

这是一个错误的错误。 rmc.latitude[10]='\0'; 将 0 放在 rmc.latitude 数组的第 11 个位置,但该数组被声明为只有 10 个位置。实际发生的是 rmc.longitude[0] 正在获取 '\0' 字符,因为它在内存中是相邻的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多