dtostrf output question

Can somebody please explain the output of the following code:

float roll = 51.75;
float pitch = 74.87;

char roll_out[2];
char pitch_out[2];

void setup() {

  Serial.begin(9600);

  dtostrf(roll, 2, 0, roll_out);
  dtostrf(pitch, 2, 0, pitch_out);

  Serial.print(roll_out[0]); 
  Serial.println(roll_out[1]); 

  Serial.print(pitch_out[0]); 
  Serial.println(pitch_out[1]); 
}
void loop() { 
}

Output:

2
75

Output that I want from the code:

52
75

I don't understand why in the first line the output is "2" instead of "52".

I don't understand why in the first line the output is "2" instead of "52".

How many characters does it take to store "52" ? Answer = 3, allowing for the terminating zero

How many characters does your target array have ? Answer = 2

Do you see a problem ?

There is no need to print each element of the array separately, Serial.print(roll_out) will work because print() can handle null-terminated char arrays produced by dtostrf()

UKHeliBob: How many characters does it take to store "52" ? Answer = 3, allowing for the terminating zero

How many characters does your target array have ? Answer = 2

Do you see a problem ?

Hi HeliBob, could you explain this further? What is a terminating zero and why does the second value print as expected?

In C language, strings are actually arrays of characters. This seems like they would have to be only fixed length strings, the length of the array. To allow strings to be shorter than the length of the array, C functions like dtostrf() put a zero character after the last character they make. Other functions like Serial.print() use this zero character to know where the string ends and do not print the other characters from the array that come after that. So the zero character terminates the string.

In order to hold the zero character, you must always make your character arrays one character longer than you need. If you don't, functions like dtostrf() will write to memory locations that are not part of the character array, and may be part of another variable. This can give some strange errors, like the one you have seen.

The reason your second string prints as expected is random luck. That character array is also too short, but perhaps the memory locations after it are not used.

Note: when I said "zero character" this does not mean '0', it means the ASCII character with the code 0, which is not printable, and is also called a "null character".

This produces the output you want:

void setup()
{
  Serial.begin(9600);


  Serial.println((int)(roll+0.5)); // Rounded to nearest integer
  Serial.println((int)(pitch+0.5)); // Rounded to nearest integer
}