CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

A little guidance using strtok please

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JerryR



Joined: 07 Feb 2008
Posts: 164

View user's profile Send private message

A little guidance using strtok please
PostPosted: Thu Mar 27, 2008 10:23 am     Reply with quote

I am attempting to parse comma separated fields from a GPS-generated (nmea-0183) array of chars using strtok. I am running into a problem that I need help with. Using 3.249 PCWH compiling code for a PIC18F4525 controller.

Here a code snippet:
Code:

{

float    UTC;                                               //Complete UTC float
int8     UTC_Hours;                                         //UTC hours
int8     UTC_Mins;                                          //UTC min
int8     UTC_Secs_Int;                                      //UTC seconds
int16    UTC_Secs_Frac;                                     //UTC frac seconds

char     Status;

float    Lat;                                               //Complete Lat. float
int8     Lat_Deg;                                           //Lat. Degrees
int8     Lat_Min;                                           //Lat. Minutes
int16    Lat_Min_Frac;                                      //Lat. Frac Minutes
char     N_S;                                               //North =1, S =0

float    Lon;                                               //Complete Lon. float
int8     Lon_Deg;                                           //Long. Degrees
int8     Lon_Min;                                           //Long. Minutes
int16    Lon_Min_Frac;                                      //Long. Frac Minutes
char     E_W;                                               //East =1, W =1

float    Speed;                                             //Complete speed float

float    Course;                                            //Complete course float

int32    Date;                                              //complete date

int8     Rx_CheckSum;                                       //8 bit checksum received

char     Term[1];
int8     Index;

char     *Field;

strcpy(Term,",");                                           //load delimiter ","

Field = strtok(Working_GPS_Str, Term);                      //parse to next delimiter

UTC =    atof(strtok(0, Term));                             //get UTC time float
Status =  strtok(0, Term);                                  //get status char (A or V)
Lat =  atof(strtok(0, Term));                               //get latitude float
N_S =  strtok(0, Term);                                     //get N_S char (N or S)
Lon =  atof(strtok(0, Term));                               //get longitude float
E_W =  strtok(0, Term);                                     //get E_W char (E or W)
Speed =  atof(strtok(0, Term));                             //get speed float
Course = atof(strtok(0, Term));                             //get course float 
Date =   atoi32(strtok(0, Term));                           //get date
delay_us(1);                                                        //stopping point for
                                                                           //debugger



The ASCII string to parse is:

$GPRMC,161229.487.A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10

All number (float) are parsed fine. However the "A", "N", "W" are parsed incorrectly. The results are: Status= '2' (0x32), N_S= '>', and E_W= 'K'.

Anyone see my mistake?

Thanks in advance!
Matro
Guest







PostPosted: Thu Mar 27, 2008 10:34 am     Reply with quote

Just add a line at the beginning where you set the string to parse. Just to see if the problem isn't there. Use a constant string for demo.

Matro.
JerryR



Joined: 07 Feb 2008
Posts: 164

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 10:57 am     Reply with quote

Thanks for the quick reply Matro. Good suggestion, but still same result. The solution will probably be pretty simple. Here's the code with the "canned" GPS string forced into it.

Code:

Parse_CkSum_GPS(*Working_GPS_Str)
{

float    UTC;                                               //Complete UTC float
int8     UTC_Hours;                                         //UTC hours
int8     UTC_Mins;                                          //UTC min
int8     UTC_Secs_Int;                                      //UTC seconds
int16    UTC_Secs_Frac;                                     //UTC frac seconds

char     Status;

float    Lat;                                               //Complete Lat. float
int8     Lat_Deg;                                           //Lat. Degrees
int8     Lat_Min;                                           //Lat. Minutes
int16    Lat_Min_Frac;                                      //Lat. Frac Minutes
char     N_S;                                               //North =1, S =0

float    Lon;                                               //Complete Lon. float
int8     Lon_Deg;                                           //Long. Degrees
int8     Lon_Min;                                           //Long. Minutes
int16    Lon_Min_Frac;                                      //Long. Frac Minutes
char     E_W;                                               //East =1, W =1

float    Speed;                                             //Complete speed float

float    Course;                                            //Complete course float

int32    Date;                                              //complete date

int8     Rx_CheckSum;                                       //8 bit checksum received

char     Term[1];
int8     Index;

char     *Field;

strcpy (Working_GPS_Str, "GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598");

strcpy(Term,",");                                           //load delimiter ","

Field = strtok(Working_GPS_Str, Term);                      //parse to next delimiter

UTC =    atof(strtok(0, Term));                             //get UTC time float
Status =  strtok(0, Term);                                  //get status char (A or V)
Lat =  atof(strtok(0, Term));                               //get latitude float
N_S =  strtok(0, Term);                                     //get N_S char (N or S)
Lon =  atof(strtok(0, Term));                               //get longitude float
E_W =  strtok(0, Term);                                     //get E_W char (E or W)
Speed =  atof(strtok(0, Term));                             //get speed float
Course = atof(strtok(0, Term));                             //get course float 
Date =   atoi32(strtok(0, Term));                           //get date
delay_us(1);
JerryR



Joined: 07 Feb 2008
Posts: 164

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 11:02 am     Reply with quote

And another thing... It doesn't matter what character I put in the "A" position, the result for Status is still '2' (ASCII).

Any other thoughts?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 11:07 am     Reply with quote

Strip the program down to essentials. Use a very short test string
that consists just of "A,B,C" or something like that. Get rid of most
of those variables. Then try to parse out the A,B,C chars. Post a
complete, compilable test program, with the #include,#fuses, #use
delay, and a main() and the printf() statement that displays the result
of the parsing. In other words, post a (very short -- 10 lines) program
that I can copy and paste into MPLAB and run in the MPSIM simulator.

Also post your compiler version.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 11:29 am     Reply with quote

Code:
char     Term[1];
...
strcpy(Term,",");                                           //load delimiter ","
Your Term array should be large enough to contain the string + terminating zero. Now it is 1 character too small and strcpy will overwrite memory with unpredictable results.

Second problem:
Code:
Status =  strtok(0, Term);                                  //get status char (A or V)
Strtok returns a pointer, not a value.
JerryR



Joined: 07 Feb 2008
Posts: 164

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 12:08 pm     Reply with quote

ckielstra, PCM:

Thanks for your replies. Yes, Yes strtok returns a pointer! I dropped my "*".

Thanks so much!
Matro
Guest







PostPosted: Thu Mar 27, 2008 12:14 pm     Reply with quote

I just think the same thing.
strtok() returns a pointer and not a value.
That's why it works when you use atof() that takes a pointer too in parameter.
Use that code:
Code:

UTC =    atof(strtok(0, Term));                             //get UTC time float
Status =  *strtok(0, Term);                                  //get status char (A or V)
Lat =  atof(strtok(0, Term));                               //get latitude float
N_S =  *strtok(0, Term);                                     //get N_S char (N or S)
Lon =  atof(strtok(0, Term));                               //get longitude float
E_W =  *strtok(0, Term);                                     //get E_W char (E or W)
Speed =  atof(strtok(0, Term));                             //get speed float
Course = atof(strtok(0, Term));                             //get course float
Date =   atoi32(strtok(0, Term));



Matro
Guest








Thanks Matro
PostPosted: Thu Mar 27, 2008 12:33 pm     Reply with quote

Matro:

Yes, that's what I did to fix it. I didn't catch the pointer issue!

Thanks for your interest!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group