How to set a cell of an object String to empty char?

Hi everyone,
I have this problem using Arduino Mega2560 and Arduino IDE 1.6.5: the output of this code

  GNGGA = ",,,,,,0,00,99.99,,,,,,";
  GNGGAtoSend = findStr(GNGGA,1,2);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = '\0';
  Serial2.println(GNGGAtoSend);

String findStr(String str, int virgolaIn, int virgolaFin)
  {
  int a = 0;
  int virgole = 0; 
  int inizio = 0;
  boolean controllo = true;
  while(virgole < virgolaFin)
  {
    if (str[a] == ',') 
    { 
      virgole = virgole + 1;
    } 
    if (controllo == true)
    {
      if (virgole == virgolaIn)
      {
       inizio = a;
       controllo = false;
      }
    }
    a = a+1;
  }

is ,. And the . (dot) is related to the assignment GNGGAtoSend[GNGGAtoSend.length() - 1] = '\0'; because if I change to another char the assignment the dot disappear.

The same if I write

  GNGGAtoSend[GNGGAtoSend.length() - 1] = '\0';

Or

  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;

Or if I use setCharAt method.

Any solutions?
Thanks in advance.

NG

Any solutions?

Yes. The fine folks at http://snippets-r-us.com are there to help you with snippets. We're not. We are expecting to see ALL of your code.

No problem man.

/*
 GPS Level Convertor Board Test Script
 03/05/2012 2E0UPU
 
 This example connects the GPS via Software Serial.
 Initialise the GPS Module in Flight Mode and then echo's out the NMEA Data to the Arduinos onboard Serial port.
 
 This example code is in the public domain.
 Additional Code by J Coxon (http://ukhas.org.uk/guides:falcom_fsa03)
 
 
                     COLLEAGAMENTI
                     arduino ---------- GPS
                     GND,VCC            GND,VCC
                     D10                RX
                     D9                 TX
 !!!!!!!!! PIN ENABLE GPS collegato a VCC (5V) !!!!!!!!!!

 COLLEAGAMENTI
                     arduino mega ---------- GPS
                     GND,VCC                 GND,VCC
                     TX1                     RX
                     RX1                     TX
                     TX2                     TX SerialToUSB
 !!!!!!!!! PIN ENABLE GPS collegato a VCC (5V) !!!!!!!!!!
 
 */
 
byte gps_set_sucess = 0 ;

String GNGGA = String();
String PUBX  = String();
String GNGGAtoSend = String();

void setup()
{
  //pinMode(2,OUTPUT);
  //digitalWrite(2,LOW);
  Serial1.begin(9600); 
  // START OUR SERIAL DEBUG PORT
  Serial2.begin(9600);
  Serial2.println("Serial1 Level Convertor Board Test Script");
  Serial2.println("03/06/2012 2E0UPU");
  Serial2.println("Initialising....");
  //
  // THE FOLLOWING COMMAND SWITCHES MODULE TO 4800 BAUD
  // THEN SWITCHES THE SOFTWARE SERIAL TO 4,800 BAUD
  //
  Serial1.print("$PUBX,41,1,0007,0003,4800,0*13\r\n"); 
  delay(1000);
  Serial1.begin(4800);
  Serial1.flush();
 
  //  THIS COMMAND SETS FLIGHT MODE AND CONFIRMS IT 
  Serial2.println("Setting uBlox nav mode: ");
  uint8_t setNav[] = {
    0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 
    0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC }; //44byte
  while(!gps_set_sucess)
  {
    sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t));
    gps_set_sucess=getUBX_ACK(setNav);
  }
  gps_set_sucess=0;
 
  // THE FOLLOWING COMMANDS DO WHAT THE $PUBX ONES DO BUT WITH CONFIRMATION
  // UNCOMMENT AS NEEDED
  
  Serial2.println("Switching off NMEA GLL: ");
   uint8_t setGLL[] = { 
   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B}; //16byte
   while(!gps_set_sucess)
   {    
   sendUBX(setGLL, sizeof(setGLL)/sizeof(uint8_t));
   gps_set_sucess=getUBX_ACK(setGLL);
   }
   gps_set_sucess=0;
   Serial2.println("Switching off NMEA GSA: ");
   uint8_t setGSA[] = { 
   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32}; //16byte
   while(!gps_set_sucess)
   {  
   sendUBX(setGSA, sizeof(setGSA)/sizeof(uint8_t));
   gps_set_sucess=getUBX_ACK(setGSA);
   }
   gps_set_sucess=0;
   Serial2.println("Switching off NMEA GSV: ");
   uint8_t setGSV[] = { 
   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39}; //16byte
   while(!gps_set_sucess)
   {
   sendUBX(setGSV, sizeof(setGSV)/sizeof(uint8_t));
   gps_set_sucess=getUBX_ACK(setGSV);
   }
   gps_set_sucess=0;
   Serial2.print("Switching off NMEA RMC: ");
   uint8_t setRMC[] = { 
   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40}; //16byte
   while(!gps_set_sucess)
   {
   sendUBX(setRMC, sizeof(setRMC)/sizeof(uint8_t));
   gps_set_sucess=getUBX_ACK(setRMC);
   }
   gps_set_sucess=0;
   Serial2.print("Switching off NMEA VTG: ");
   uint8_t setVTG[] = { 
   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46}; //16byte
   while(!gps_set_sucess)
   {
   sendUBX(setVTG, sizeof(setRMC)/sizeof(uint8_t));
   gps_set_sucess=getUBX_ACK(setVTG);
   }
}
 
void loop()
{
  readPUBX_GNGGA();
  findUBloxToSend();
  //Serial2.println(findStr(PUBX,5,6));
} 

void findUBloxToSend(){
  char* appoggio;
  GNGGAtoSend = findStr(GNGGA,1,2);
  GNGGAtoSend[GNGGAtoSend.length() - 1] =  ;
  /*GNGGAtoSend += findStr(GNGGA,2,3);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;
  GNGGAtoSend += findStr(GNGGA,4,5);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;
  GNGGAtoSend += findStr(GNGGA,6,7);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;
  GNGGAtoSend += findStr(GNGGA,7,8);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;
  GNGGAtoSend += findStr(GNGGA,9,10);
  GNGGAtoSend[GNGGAtoSend.length() - 1] = 0;
  GNGGAtoSend += findStr(PUBX,13,14); 
  //GNGGAtoSend.trim();*/
  Serial2.println(GNGGAtoSend);
  Serial2.println();
}

void readPUBX_GNGGA(){
  while(!Serial1.available());
  while(Serial1.available())
  {
    Serial1.readStringUntil('

);
    Serial1.readStringUntil(‘A’);
    GNGGA = Serial1.readStringUntil(’’);
  }
  while(!Serial1.available());
  Serial1.println("$PUBX,00
33");
  while(Serial1.available())
  {
    Serial1.readStringUntil(’$PUBX’);
    PUBX = Serial1.readStringUntil(’*’);
  }
  Serial2.print("GNGGA : ");
  Serial2.println(GNGGA);
  Serial2.print("PUBX : ");
  Serial2.println(PUBX);
  Serial2.println();
  }

String findStr(String str, int virgolaIn, int virgolaFin)
  {
  int a = 0;
  int virgole = 0;
  int inizio = 0;
  boolean controllo = true;
  while(virgole < virgolaFin)
  {
    if (str[a] == ‘,’)
    {
      virgole = virgole + 1;
    }
    if (controllo == true)
    {
      if (virgole == virgolaIn)
      {
      inizio = a;
      controllo = false;
      }
    }
    a = a+1;
    //Serial2.println(virgole);
  }
  //Serial2.println(inizio);
  //Serial2.println(a);
  return str.substring(inizio,a);
  }

/*  int a = 0, virgole = 0, inizio = 0;
  boolean controllo = true;
  while(virgole < 14)
  {
    if (PUBX[a] == ‘,’)
      virgole++;
    if (controllo)
      if (virgole == 13)
      {
      inizio = a;
      controllo = false;
      }
    a++;
  }
  String velVert = String();  //globale
  velVert = PUBX.substring(inizio,a);
  Serial2.println(velVert);*/

// Send a byte array of UBX protocol to the GPS
void sendUBX(uint8_t *MSG, uint8_t len) {
  for(int i=0; i<len; i++) {
    Serial1.write(MSG[i]);
    Serial2.print(MSG[i], HEX);
  }
  Serial1.println();
}

// Calculate expected UBX ACK packet and parse UBX response from GPS
boolean getUBX_ACK(uint8_t *MSG) {
  uint8_t b;
  uint8_t ackByteID = 0;
  uint8_t ackPacket[10];
  unsigned long startTime = millis();
  Serial2.print(" * Reading ACK response: ");

// Construct the expected ACK packet   
  ackPacket[0] = 0xB5;  // header
  ackPacket[1] = 0x62;  // header
  ackPacket[2] = 0x05;  // class
  ackPacket[3] = 0x01;  // id
  ackPacket[4] = 0x02;  // length
  ackPacket[5] = 0x00;
  ackPacket[6] = MSG[2];  // ACK class
  ackPacket[7] = MSG[3];  // ACK id
  ackPacket[8] = 0;  // CK_A
  ackPacket[9] = 0;  // CK_B

// Calculate the checksums
  for (uint8_t i=2; i<8; i++) {
    ackPacket[8] = ackPacket[8] + ackPacket[i];
    ackPacket[9] = ackPacket[9] + ackPacket[8];
  }

while (1) {

// Test for success
    if (ackByteID > 9) {
      // All packets in order!
      Serial2.println(" (SUCCESS!)");
      return true;
    }

// Timeout if no valid response in 3 seconds
    if (millis() - startTime > 3000) {
      Serial2.println(" (FAILED!)");
      return false;
    }

// Make sure data is available to read
    if (Serial1.available()) {
      b = Serial1.read();

// Check that bytes arrive in sequence as per expected ACK packet
      if (b == ackPacket[ackByteID]) {
        ackByteID++;
        Serial2.print(b, HEX);
      }
      else {
        ackByteID = 0;  // Reset and look again, invalid order
      }
    }
  }
}

String GNGGA = String();

Does this do something different from:

String GNGGA;

Why are you pissing resources away using Strings?

  Serial1.begin(4800);
  Serial1.flush();

Wait for all pending outgoing serial data to have been send, immediately after opening the serial port, having sent nothing. Why on earth are you doing that?

  char* appoggio;

You should NEVER declare a pointer with pointing it to something or setting it to NULL.

  GNGGAtoSend = findStr(GNGGA,1,2);

The String GNGGA has never been assigned a value. Nothing from this point on can be expected to work.

Maybe you don't understand. Until the call to function findUBloxToSend() all works as I want. I spent hours of debug before post. I don't have any time to change my working code, I only want to know how I can put the last char of a String obj to '\0'. I think is quiet easy to understand.

If you were using char arrays instead of Strings this would be trivial. I don't know how the String object handles its backing array so I don't know how you would do this with String object. I don't like wasting resources or random crashes so I tend to stay away from the String object when I'm working on microcontrollers.

Delta_G:
If you were using char arrays instead of Strings this would be trivial. I don’t know how the String object handles its backing array so I don’t know how you would do this with String object. I don’t like wasting resources or random crashes so I tend to stay away from the String object when I’m working on microcontrollers.

You are right but If you see the implementation (very simple to understand) it only gives some useful operands and method without using C++ standard functions. So I think that in my case this class could help me saving time.
Thanks.

nicologhielmetti:
You are right but If you see the implementation (very simple to understand) it only gives some useful operands and method without using C++ standard functions. So I think that in my case this class could help me saving time.
Thanks.

I don't think you understand. The String object accomplishes all of this using dynamic memory allocation. That's a bit dangerous on a micro with no garbage collector. Memory tends to end up fragmented.

You have to think about HOW the String object introduces all of those conveniences to see why it is frowned upon in systems with limited memory.

And that has walked away from the fact that you are now having a specific problem with the String object that you simply wouldn't have if using char arrays.

Strings are great until you run into their limitations and have to rewrite a bunch of code.

I think what you are going to have to do to stay with String is to create a new String and give it the first part that you want to keep, add the 0, and then add whatever you want after the 0.

What I don't know is whether or not String can deal with a 0 in the middle. It may fail thinking that's a null terminator.

Until the call to function findUBloxToSend() all works as I want.

But, you have not assigned a value to GNGGA, so when everything goes to hell in that function, don't expect me to be surprised.

I don't have any time to change my working code

Then, you are f**ked.

I only want to know how I can put the last char of a String obj to '\0'.

The last element of the char array that the String wraps already contains a NULL.

I think is quiet easy to understand.

Well you don't seem to get it. So, possibly it is not as easy as you think.