Strcat() not doing the '|' pipe character ?

Short story - been using this code in wireless sensors for years - but today it failed to work after I made some additions to the 'sensor reading section' - compiled fine. It seems my choice of the 'pipe' as a delimiter (made years ago) is now the only character that strcat() is failing to do??? A 'freeMemory() check before-after says about 2000. Is this a heap thing?

Your msg[48] is an uninitialised variable; the terminating nul character that is needed by the str functions can be anywhere in RAM. Below will more than likely solve that problem

char msg[48];
msg[0]='\0';

If it does not solve the problem, please post a representable example.

The code (pictured instead of posted, so hard to read), uses strcpy() to put an initial "1" into msg, which will properly terminate the char array. The code is not auto-formatted, so a bit hard to see that all the strcpy() and strcat() code is within an if statement.

I have no problem with strcat() and the pipe symbol on an UNO.

1 Like

OOPS, missed that one. A good reason to post code as text.

3 Likes

Whatever the problem actually is, I don't think it's in the snippet you've shown.

void packet_SEND1(int sbn, const char *id, double bv, const char *data) {
   Serial.println(F("packet_SEND1"));
   Serial.flush();
   char n2a[10];
   char msg[48];
   char dlm[4];

   strcpy(dlm, "|");
   
   if( data[0] != 0 ) {
      strcpy(msg, "1");
      Serial.println(msg);

      strcat(msg, dlm);
      strcat(msg, id);
      Serial.println(msg);

      strcat(msg, dlm);
      itoa(sbn, n2a, 10);
      strcat(msg, n2a);
      Serial.println(msg);

      strcat(msg, dlm);
      dtostrf(bv, 1, 1, n2a);
      strcat(msg, n2a);
      Serial.println(msg);

      strcat(msg, dlm);
      strcat(msg, data);
      Serial.println(msg);
   }
}

void setup() {
   Serial.begin(115200);
   Serial.println();
   packet_SEND1(1, "8X4RZD", 3.0, "PUSH");
}

void loop() {
}
packet_SEND1
Connecting to /dev/ttyACM0. Press CTRL-C to exit.

1
1|8X4RZD
1|8X4RZD|1
1|8X4RZD|1|3.0
1|8X4RZD|1|3.0|PUSH

it is very difficult to read the screen image of code in post 1 - as @sterretje recommends post code as text using code tags </>
why not initialize your local variables when you define them, e.g.

  char msg[48]={0};
  char dlm[4]="|";

Will try - I guess I thought that first strCPY("1") would do that.

Not going to ask why - just happy that @horace made me do it - because it's worked! And while I may speculate about what weird character may have been in the un-init'd msg[] that caused that - I'm also reminded that I used to code properly like that and I've just gotten sloppy. Kick in butt appreciated. :slight_smile:

You might have a bug somewhere in your code that causes the behaviour.

1 Like

It really seems like an out-of-bounds write to an array somewhere else in the code, a stack overflow, etc, that is overwriting ram. Any change in the code moves the variables around and the problem will appear to go away.

1 Like

just in case you are using uninitialized local variables with garbage in them it maybe worth explicitly initializing all your local variables, e.g.

 char n2a[10]={0};

also recommend you use strncat(), strncpy(), etc where the target size is specified

may help find your problem

I'm guessing it was a heap-stack conflict thing. It did more odd things elsewhere after that part worked. Strcpy() was used in several 'cases' of a switch-case. A strcpy() in 'case 1:', (after 'case 0:' and before 'case 2:') was screwing up. When I swapped the position of 'case 1:' with 'case 2:' - so it was third in the switch list - it worked and 'case 2:' screwed up. WHERE it was in the code mattered - like it was a bad RAM location. But it wasn't. I put a bunch of little string assignments into PROGMEM , used strlcpy_P() and strcmp_P() and the weirdness went away.
Here's what compiler reported for this program... "Global variables use 1348 bytes (65%) of dynamic memory. ". So... I'm going to pay attention to 'dynamic memory' - not let it get over 1300 on the '328.