# build fixed size strings from floats

This is likely a duplicate, but I couldn't find the original question. This is really basic, but just can't figure it out.

I'm trying to combine a few char arrays together. This is what I've tried so far.

``````float a = 12.3456;
float b = 5.4321;
bool c = true;

char a_string[4];
dtostrf(a, 4, 1, a_string);

char b_string[4];
dtostrf(b, 4, 1, b_string);

char c_string[2] = {'0', '\0'};
if (c) {
c_string[0] = '1';
}

char output[12] = "-----------";

output[0] = a_string[0];
output[1] = a_string[1];
output[2] = a_string[2];
output[3] = a_string[3];

output[4] = ' ';

output[5] = b_string[0];
output[6] = b_string[1];
output[7] = b_string[2];
output[8] = b_string[3];

output[9] = ' ';

output[10] = c_string[0];

Serial.println(output);
``````

Results in an empty string in seems.

If I remove the second dtostrf(), and change b_string[0] ... to a_string[0] Then I get `12.3 12.3 1`. Doesn't seem to like having dtostrf() called more than once, but it seems like the function I want, since it allows me to set a fixed strint size. The output I'd be looking for is `12.3 5.4 1`

another approach

``````String a_string = String(a, 1);
String b_string = String(b, 1);
String c_string = String(c);

String output;
String space = " ";

output.concat(a_string);
output.concat(space);
output.concat(b_string);
output.concat(space);
output.concat(c_string);

Serial.println(output);
``````

This outputs `12.3 5.4 1`. Is there a way to make the String fixed width? I'm looking for

`12.3 5.4 1` instead of

`12.3 5.4 1`

What's the proper way of doing this?

## EDIT

After trying to use the @Majenko's answer I sometimes get garbage values printed. Any ideas why?

``````float a = analogRead(A1) / 1023.;
float b = analogRead(A2) / 1023.;
bool c = analogRead(A3) / 1023;

char* output = createString(a, b, c);
Serial.println(output);

char* createString (float _a, float _b, bool _c)
{
char a_string[5];
dtostrf(_a, 4, 1, a_string);

char b_string[5];
dtostrf(_b, 4, 1, b_string);

char out[12];
snprintf(out, 12, "%4s %4s %d", a_string, b_string, c ? 1 : 0);
return out;
}
``````

and the output:

`````` 0.6  1.0 0
0.6  1.0 0
0.6  1.0 0
0.6  1.0 0
0.6  1.0 0
0.6  1.0 0
0.�tS
�
0.6  `S
�
0.6  1.0
}
0.6  1.0 0
0.7  1.0 0
0.6  1.0 0
0.6  1.0 0
``````

using

``````  Serial.print(a_string);
Serial.print(" ");
Serial.print(b_string);
Serial.print(" ");
Serial.println(c);
``````

doesn't produce the errors

• Other than figuring out how long each string is or using `*printf()`? Apr 25, 2016 at 19:00

## 1 Answer

The simple way would be to format the string with `sprintf` - however `sprintf` on the Arduino lacks floating point support (although it is possible to enable it).

So if you convert your floating point numbers into strings first (remember to provide room for the NULL terminating character!) you can then use `sprintf` to format those converted numbers into what you want:

``````float a = 12.3456;
float b = 5.4321;
bool c = true;

char a_string[5];
dtostrf(a, 4, 1, a_string);

char b_string[5];
dtostrf(b, 4, 1, b_string);

char out[12];

snprintf(out, 12, "%4s %4s %d", a_string, b_string, c ? 1 : 0);
``````

`%4s` is replaced by a string which is padded to at least 4 characters wide. The padding is to the left of the string. If you want the padding to the right you can use `%-4s` instead.

# Addendum:

In your new posted code you are making a fundamental error:

``````char out[12];
snprintf(out, 12, "%4s %4s %d", a_string, b_string, c ? 1 : 0);
return out;
``````

`out` is a local variable to the function. Its memory is allocated on the stack. You fill that with data and then return the address of that location on the stack. As soon as you leave the function that memory allocation is lost. Yes, the data is still there, but the moment you call another function that memory gets overwritten with the call frame of the new function you have called - thus corrupting your data.

You have two main options:

1. Make `out` global
2. Make `out` static

The effect of the two options is pretty much the same, except that in the second option the scope of `out` is restricted to the function which means you can use the name `out` elsewhere without it conflicting. In both options though the memory allocated to `out` is in the BSS not the stack and thus won't get overwritten.

• Thanks, that works great. When I try to use analogRead values for it though I sometimes get garbage. I updated by question. Any ideas? May 4, 2016 at 14:52
• See my addendum. May 4, 2016 at 14:56