0
votes

i'm currently trying to debug my program over UART by printing the values of some variables at specific points. My issue is with printing two char arrays. The order in which i print them seems to have an effect on if it prints. The declarations of the arrays are in a struct in a header file as follows-

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

NMEA_RMC_t rmc;

The char arrays are manipulated in another function after parsing data from an input. They are not updated with an interrupt, although there are interrupts elsewhere in the program. In the main code if i print them as follows-

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

the output to the terminal is this-

lat: +50.71735 long:

whereas if i print them in a different order like this-

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

i get this output.

long: -001.39118 lat:

also if i split the printing up into two separate printf statements, only the first print statement correctly prints the char array. I haven't had to ask for help on here before but this has had me stuck for a good week now. Any help would be massively appreciated! cheers.

edit

The part of the program that writes into the array is this. its essentially the same for the latitude and longitude array.

/* 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';

essentially it is parsing the information from a stream of data coming in.

2
And how do you initilize your arrays? - Fredrik
I suspect it could be related to the UART receiver. Maybe the rest of the string is yet to be read from the lower layer. How much is the Rx buffer size? Are you sure you've read all bytes from the UART sender? - wyc
Even if i print the two arrays in two separate printf statements, the second one never works correctly - regardless of which is first. i tried printing some large text and all of it went through fine. Thank you for your suggestion. - George Stokes
@GeorgeStokes, just see your update. rmc.latitude[10]='\0' actually put '\0' to longitude[0]. Try rmc.latitude[9]='\0' - wyc

2 Answers

1
votes

For %s to work correctly, the char array must have a NUL-terminator \0 which signifies the end of the string.

If you don't leave room for that, the behaviour of your program is undefined.

You need to initialise the arrays yourself - don't rely on the compiler to do it.

Get your debugger out and check the memory associated with rmc at the point of the printf.

0
votes

Your code for converting the strings and putting them in the struct is inadvertently placing a '\0' character at the beginning of rmc.longitude. The code then goes on the fill the rest of the array with the correct value, but the printf() function sees rmc.longitude as a zero-length string and ignores what follows.

It is an an off-by-one error. rmc.latitude[10]='\0'; places a 0 in the 11th position of the rmc.latitude array, but this array was declared to only have 10 positions. What is actually happening instead is rmc.longitude[0] is getting the '\0' character, as it is adjacent in memory.