-1
\$\begingroup\$

I wrote a code to simulate receiving NMEA string from my GPS, but faced a problem in parsing the latitude, longitude and date, i want to know what is the problem with the code . here is my code :

    void GPS_parseSTR(char *lat,char *lon,char *day,char *month,char *year,char *string){
int i;
for (i=0;i<9;i++)
{
lat[i]=string[i+14];
lat[i+1]='\0';
}

int j;
for (j=0;j<10;j++){
lon[j]=string[j+26];
lon[j+1]='\0';}

int k;
for (k=0;k<2;k++){
day[k]=string[k+49];
day[k+1]='\0';}

int l;
for (l=0;l<2;l++){
month[l]=string[l+51];
month[l+1]='\0';}

int m;
for (m=0;m<2;m++){
year[m]=string[m+53];
year[m+1]='\0';
              } 
           }

int main(){

 char lat[9];
 char lon[10];
 char day[2];
 char month[2];
 char year[2];
 char string[55]=",075747.000,A,2232.8990,N,11405.3368,E,3.9,357.8,260210" ;
 GPS_parseSTR(lat,lon,day,month,year,string);

printf("%s\n",lat);
printf("%s\n",lon);
printf("%s\n",day);
printf("%s\n",month);
printf("%s\n",year);
return 0 ;
}
\$\endgroup\$
5
  • 3
    \$\begingroup\$ Not really sure why this is here instead of Stack Overflow. There's no electronics in this question. \$\endgroup\$ Apr 30, 2015 at 1:14
  • 1
    \$\begingroup\$ C strings need to leave room for the \0 terminator. \$\endgroup\$
    – user572
    Apr 30, 2015 at 3:08
  • \$\begingroup\$ char lat[9+1]; char lon[10+1]; char day[2+1]; char month[2+1]; char year[2+1]; // reserve space for string terminator '\0' \$\endgroup\$
    – MarkU
    Apr 30, 2015 at 4:54
  • \$\begingroup\$ @user572: thanks a lot, i didn't notice this point (Y) \$\endgroup\$ Apr 30, 2015 at 10:48
  • 3
    \$\begingroup\$ Off topic, no electronic or hardware-relevant code here. \$\endgroup\$ Apr 30, 2015 at 14:02

1 Answer 1

4
\$\begingroup\$

Although MarkU and user572's comments have solved your immediate problem by pointing out that an extra byte is required to hold the null terminator you have another underlying problem that means this code won't work reliably with real GPS data. To take your example section of an RMC sentence:

,075747.000,A,2232.8990,N,11405.3368,E,3.9,357.8,260210

The value 3.9 is the speed in knots, as the speed increases the sentence may become:

,075747.000,A,2232.8990,N,11405.3368,E,10.1,357.8,260210

Now your date has moved across by one character and similar things will happen when the course becomes lower than 100. When in different locations the same may happen with the latitude and longitude as the number of digits change and also different receivers use different rules for when trailing and leading zeroes are dropped. So this code wouldn't be portable and in general trying to treat GPS sentences as fixed length strings is a bad idea.

A better idea is to treat each field as variable length by parsing each field as you go along and move to the next field when you encounter a comma. In embedded systems I normally write that code as a state machine so that the data can be processed character by character as it arrives, but a simpler way as you're processing the whole string at once would be to use the strtok() function using the comma character as the delimeter.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Indeed, treating ANY delimited data set as fixed length is a bad idea. Generally true fixed length fields don't use any delimiter... because, well, they're fixed length. \$\endgroup\$ Apr 30, 2015 at 13:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.