How to copy part of a char array into an otner char array

Hello everyone,

I am writing a code for a project that uses NMEA sentences received from the serial port and stored into char array. The NMEA sentences are actually ASCII character fields separated by commas. Is there an easy way to copy specific fields from the char array into a new char array ?

Here is an example of the contents of the first char array :
$GPGGA,133212.00,3557.910,N,02130.187,E,1,04,1.762,18.65,M,-35.2,M,,*48

In this example sentense i would like to copy the indocated part (bold letters) into an other char array named Lat.
$GPGGA,133212.00,3557.910,N,02130.187,E,1,04,1.762,18.65,M,-35.2,M,,*48

in this particular example case the desiered field is the 3rd one.
To complicate things more, in many occasion there may be empty fields like for example:
$GPGGA,,3557.910,N,02130.187,E,,,,18.65,M,-35.2,M,,*48
In this case now there is an empty field before the desired 3rd field.

Do i make sense ? THANKYOU

Why not use a GPS library ?
The values will be available to you having been parsed by the library

If you want to do it yourself then take a look at the strtok() function as a starting point but the empty fields may cause a problem

You could, of course, write your own parsing function that read the data string character by character, counted the commas and built the output strings when the correct part of the data was reached. If the input data were guaranteed to be always of exactly the same format and layout it would be even easier to parse

I am not using the gps library because the project's code has already been written and debuged and now im only making small modifications.

Indeed the empty fields are a problem and i have no way of predicting the presence of them.
I guess i could copy character by character but the fields are not of equal length every time :frowning: for example one field may be like this 3557.910 and an other like this 3557.9100

P.S. strtok() is indeed a no go due the the empty fields

If you count the commas as they are received then it does not matter whether fields are empty or change in length

1 Like

Here is an other part of the code that kind of works in a similar way

void GPSparseData()
{
  char *commaPtr = 0 ;  
  int CommaCount = 0;   
  commaPtr = strchr(GPS.RcvdChars, ',');
  while (commaPtr != NULL || CommaCount < 8) 
  {
    CommaCount++;   
    if (CommaCount == 7) 
    {
      GPS.SatCount = atoi(commaPtr + 1); 

    }                                   
    commaPtr = strchr(commaPtr + 1, ',');
  }
}

If you are going to make any changes to it then the code will need to be tested and debugged again. You cannot assume that some other part may not be affected by your changes.

My suggestion would still be to use a GPS library with a proven track record to reduce the possible problems that you may have doing it yourself

That's right. I am going to re test it anyway. Re writing it from sctatch is something i want to avoid at all costs.
Have you checked out my post #6 ?

Your query seems very similar to this thread:

and the proposed solution very similar to that of post #6! :wink:

1 Like

@HellasT

Use memcpy() function:

char myArray[] = 
  "$GPGGA,133212.00,3557.910,N,02130.187,E,1,04,1.762,18.65,M,-35.2,M,,*48";

  char mySubArray[9] = {0};
  memcpy(&mySubArray, &myArray[17], sizeof mySubArray-1);
  Serial.println(mySubArray);  //shows: 3557.910

How many changes constitute writing it from scratch ?

I am not suggesting starting from scratch, but if you are going to make changes, which you are, then do it in a sensible way

That solution seems nice but the problem is that the starting point of the targeted field is not always in the 17 position in the char array due to the empty fields that the GPS receiver might output.

I do understand that the GPS library is very useful but in my case
the custom function that i now use is the receive with start and end markers suggested by Robin2 in this topic Serial Input Basics - updated. In my case it also is time critical. meaning that it keeps track off different events and the time that they took place in ways that affect the flow of the program. Messing with it will require that i have to change not only the code but the whole philosophy behind it.
Thats why i do not really want to do this. At least not yet.

Your opinion is well respected and always appreciated :slight_smile:
I think i know how deep my changes can go. More or less. Also i always keep copys of the code before and after any change i make so i sould be okay.
This code has undergone 46 changes so far and i have a copy of every one of them :slight_smile:

You are not referring to strtok() are you ?

Come to think about it i could combine this method with the one mentioned in post 2 and 6.

I could be counting commas with an index and when i hit the desiered field then use the memcpy to copy the data into the other array if i can somehow make sure that the length of the field does not change which i think does change.

No. I was referring to a function that you write yourself as you already have in the sketch

Okay so based on all the above i am now tring to "build" the algorithm and the way i see it is like this:
I am goin to create the new char array that will hold the data of the desired field, then using strchr i will locate the first , and then continue untill i hit the 2nd comma which is the "starting marker" of my desiered field (latitude information). i will increment the pointer and check for the existance of an other comma that would mean that the field is empty and if there is no comma i will copy the byte into the new array. Again i will increment the pointer to check the following byte and copy it untill i hit the next comma which will mean that the desiered field is finished. Going through the same process will get me the longtitude information also.
Am i thinking correctly ?

Hmm i think ive got it a bit wrong... I should be able to use a function to copy the contents between the commas like i do with the atoi() function or maybe since i will be able to keep the pointers of the field's starting and ending addresses i could copy byte by byte the contents of the addresses in between...

If you want to convert the text to a floating point number, you can use atof() once you have the pointer to where the number starts. You can also use strtof() or strtod(), which can also return a pointer to the next character after the number, which you can then check to see if it is the next comma.

Hello,
This is not a bad idea though i am thinking to handle the data i need to parse as a char array.