Shop OBEX P1 Docs P2 Docs Learn Events
memmove — Parallax Forums

memmove

Howdy folks, thanks for the help on the other problem. Got it solved. I am presently using memmove to parse out my gps tokens so as to move the data around.

First using the time. I can move the hrs to hrs, but when I move over two to get the min it gives me the seconds. Is there something special about memmove??



starts at line 150

Thanks

Comments

  • I think the basic cause of your problem is that the struct element gpstime is declared as an int array, and you are getting the minutes from "gpstime+1". Since gpstime is an int, "gpstime+1" is the address of the second int in the array, which is the fifth byte. I'm not sure which byte you intended to start with, but the fifth byte is probably not right. Assuming the time is formatted as "hh:mm:ss" you would need to start with the third byte. Or if it is formatted as "hhmmss" you would need the second byte. I'm not sure why you defined gpstime as an int. Maybe you intended it to be a char array.

    Another problem I see is that you are not terminating your strings with a null byte. A 2-character string should be 3 bytes long, where the third byte is 0.

    Finally, the function strtok will return a value of zero when there are no more tokens available. To make your code tolerant to errors in the input string, you should test for a zero return value to determine if the token has been successfully retrieved. Of course, if you can guarantee that the input string is always formatted correctly you don't have to worry about testing for a null pointer.
  • Looking at your code a little, Dave is almost certainly correct - gpstime should be declared as char, not int. char is a single byte value (8 bits), whereas int is a 4-byte value (32 bits). C interprets "gpstime+1" as "the start of gpstime, plus one increment of the unit size of gpstime", which is 4 bytes in this case.

  • Understood thanks
  • char gpsname[6];
    char gpstime[6];
    char fix[1];
    double lat;
    char latchar[1];
    double longitude;
    char longchar[1];
    double speed;
    double track;
    int date;
    double magvar;
    }gps;
    char RMC[80]; //gps string 
    char gpsraw;
    char tempf[20];
    

    If I make gpstime a char I get this if I make it an int it works fine
    375 x 706 - 18K
  • JasonDorieJasonDorie Posts: 1,930
    edited 2016-01-28 22:14
    It's possible that it's because you're doing things like this:
          print("zulu time:  %s\n\n", gps.gpstime);
    

    %s requires a null-terminated string (ie, ends with a zero byte). Since your struct just contains six characters in a row, followed immediately by other stuff, the print function has no idea where to stop.

    You could add a 7th character to gpstime and zero it. In fact, since you're using strcpy() to copy the string into gpstime, it's already doing the null termination for you, overwriting the first value in the next struct member with a zero. Since you fill in the "fix" value immediately after gpstime, you don't notice this.

    Anywhere you're using strcpy you need to make sure your destination buffer has room for the extra terminating character, so your struct should probably look like this:
    struct nmea{
    	char gpsname[7];
    	int gpstime[7];
    	char fix[2];
    	double lat;
    	char latchar[2];
    	double longitude;
    	char longchar[2];
    	double speed;
    	double track;
    	int date;
    	double magvar;
    }gps;
    

    Even that isn't completely safe because if your source string isn't well formatted, you could overrun your copy. For example, if you ended up with a missing comma in the source string, your string copy wouldn't terminate where you thought it would, and you'd copy more data than expected. There are versions of string copy that take a "maximum length" value that are safer, or, safest of all, if you know it's 6 characters, and it's ALWAYS 6 characters, just do this:
      strncpy(gps.gpsname,strtok(RMC, ","), 6);
      strncpy(gps.gpstime,strtok(null, ","), 6);
    


    You could also print it as six chars instead of a string, like this:
          print("zulu time:  ");
          for( int i=0; i<6; i++ )
            putChar( gps.gpstime[i] );
          print( "\n\n");
    

    ...but that doesn't fix your "null terminate" issue from using the string copy functions.
  • I think I got the sting copy problems fixed. Did some digging and have a better understanding. Again thanks for your help. Had to change my thinking and get my mind out of SPIN and FORTRAN, BASIC.

    I am going to try your latest suggestion.

  • Thanks to all I got it all working. This was my first real program in C.
  • Awesome! Good to hear. :)
Sign In or Register to comment.