serial.println not doing as expected (or confusion with char!)

This simple code is not behaving as expected.
I'm trying to print 'cat' followed by 'dog', with cat and dog stored as 3 character hex arrays.
instead of cat, dog I get cat, dogcat.
I'm sure I have a fundamental misunderstanding, but what is it please?

char one[3]={0x63,0x61,0x74}; //'cat'
char two[3]={0x64,0x6f,0x67}; //'dog'


void setup() {
  Serial.begin(9600);   //Serial port for debugging
  while(!Serial);       //wait for serial port to become available
  Serial.println ("Start"); //does as I expect
  Serial.println ("hello"); //does as I expect
  Serial.println (one); //does as I expect
  Serial.println (two); //does not do as I expect. Appears to print 'dogcat'
}

void loop() {
  // empty

}

You are missing a null character at the end of your names:char one[4]={0x63,0x61,0x74,0x00}; //'cat'
Jacques

Hi,
Thank you for your reply.
I agree, if I add nulls to the end of cat and dog I do get the output I am expecting. But can you explain why?
When I print 'dog' it is a different variable to the one that has printed 'cat'. why do I get 'dogcat'?
Is it the case that when printing hex vales like this they remain in the print buffer until a null character is found?

But can you explain why?

See this.
As to why the two variables are side by side in RAM (so printed one after the other), it must be because that is how the compiler placed them there.

How disappointing that telling the compiler the exact length of my strings when I declare them isn't enough of a clue as to where they might end.
Thank you for your help.

How disappointing that telling the compiler the exact length of my strings when I declare them isn't enough of a clue as to where they might end.

Actually, if you had declared your arrays as size 4, the null character would have had been added automatically by the compiler for you and everything would have worked...

Jacques

OK,
So If I can get over my bitterness about the C compiler...
In fact this is just a small problem in a bigger project.
I want to send a UDP string made up of smaller segments, each a series of hex characters where 0x00 is a valid hex value and doesn't mark the end of the string at all.
I had been hoping to compile the UDP string using a series of strcat statements, but now it appears every time it encounters 0x00 it thinks it has reached the end and stops.
I will have to find another way. Any pointers?
To clarify, I am not talking ascii characters here. any byte between 0x00 and 0xFF is valid.

Have you seen this? It is designed to handle just that kind of protocol.

Jacques

How disappointing that telling the compiler the exact length of my strings when I declare them isn't enough of a clue as to where they might end.

Don't see where you are "telling the compiler the exact length of my strings".

Surely when I declare:
char one[3]={0x63,0x61,0x74};
Am I not stating variable one will be 3 characters long?

udpMan1:
Surely when I declare:
char one[3]={0x63,0x61,0x74};
Am I not stating variable one will be 3 characters long?

No that is simply making space for those variables.

Serial.println (one); <-----<<<<< this asks Serial to print the array and expects that array is terminated with a \0 (null)

You could use a for()loop to print only 3 elements.

char one[3] = {0x63, 0x61, 0x74}; //'cat'
char two[3] = {0x64, 0x6f, 0x67}; //'dog'


void setup()
{
  Serial.begin(9600);   //Serial port for debugging
  while (!Serial);      //wait for serial port to become available
  Serial.println ("Start"); //does as I expect
  Serial.println ("hello"); //does as I expect
  //Serial.println (one);
  for (byte x = 0; x < 3; x++)
  {
    Serial.print(one[x]);
  }

  //Serial.println (two); //does not do as I expect. Appears to print 'dogcat'
  for (byte x = 0; x < 3; x++)
  {
    Serial.print(two[x]);
  }

}

void loop()
{
  // empty

}

But at the risk of being pedantic, isn't making space for a variable 3 bytes long a strong indicator that what I want to store there is 3 bytes long, at least the majority of the time? Especially if I then go on to state the 3 characters I wish to store in the space I have just reserved as 3 bytes big?

udpMan1:
But at the risk of being pedantic, isn't making space for a variable 3 bytes long a strong indicator that what I want to store there is 3 bytes long, at least the majority of the time? Especially if I then go on to state the 3 characters I wish to store in the space I have just reserved as 3 bytes big?

Yes. But you have to treat them as 3 bytes long too. However you printed a string of characters. Those two are different thing in the language.

So I think I get that udp.write(buffer,x) will write x characters over UDP irrespective of what they happen to be.
But I don't think I can use strcat to combine 0x02,0x01,0x00 and 0x05,0x04 in to 0x02,0x01,0x00,0x05,0x04?

How do you fill "buffer"?

Yes, because that's how strcat is implemented. It has nothing to do with the language itself. You could write your own function to combine the data. If the combined arrays have fixed size then it's easy. If they don't have fixed size, then you will have to somehow "mark" the end of the arrays.

well that really is my question.

What i want to do is:

buffer[5]
char one[3] = {0x02, 0x02, 0x00};
char two[2] = {0x05,0x04};
strcpy (buffer,one);
strcat (buffer,two);
udp.write(buffer,5)

but the 0x00 in one stops this working for me

Why not:

udp.write(one,3);
udp.write(two,2);

well that is an interesting suggestion!
I had always wanted to assemble the entire ‘packet’ before going anywhere near udp.write.
But I see your idea will do the same, particularly as I understand nothing happens until Udp.endPacket() anyway.

Maybe someone will tell me wrong here, but I believe that nothing is sent before udp.endPacket() is invoked anyway.

Jacques