New library CStringBuilder to print content to a c-string

CStringBuilder is a simple library for Arduino to print content to a c-string (zero terminated char array). Install it with Library Manager.

It inherits from Print class all the print and println methods you know from Serial or various network clients like EthernetClient and WiFiClient.

CStringBuilder adds printf method for C style formatted printing. And you can printf with formatting string from flash memory with F() macro.

CStringBuilder is useful if you want to prepare the string to send it in one piece, or you need to know the size of the string before you send it (for example for the Content-length header or chunked-encoding in HTTP).

#include <CStringBuilder.h>

const char* s = "string";
char c = 'C';
int i = 42;
float f = 5.3;

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  char buff[100];
  CStringBuilder sb(buff, 100);

  sb.print(F("Some text: "));
  sb.println(s);
  sb.print(F("Some char: "));
  sb.println(c);
  sb.print(F("HEX of char: "));
  sb.println(c, HEX);
  sb.print(F("Some integer: "));
  sb.println(i);
  sb.print(F("Some float: "));
  sb.println(f, 2);

  Serial.print("size to print: ");
  Serial.println(sb.length());
  Serial.println();
  Serial.println(buff);

  sb.reset();
  sb.printf(F("Formated: %s;%c;%05d\r\n"), s, c, i);
  Serial.println(buff);
}

void loop()
{

}

output

size to print: 85

Some text: string
Some char: C
HEX of char: 43
Some integer: 42
Some float: 5.30

Formated: string;C;00042

I've found this sort of thing useful when trying to optimize network communication speed. The Print class does some conversions in multiple steps (including one character at a time in the case of F() macro's __FlashStringHelper type), which causes the string to be sent by transmitting multiple segments. At least with TCP there is a lot of overhead for each segment so that is much slower than sending an entire string as a single transmission.

Yes the network optimization was one of reasons I decided to make this library. I am thinking to add a derived class for chunked encoding. it would printout the length and then the context of the buffer to underlying stream always when the buffer is full. But perhaps the HttpClient should do this.

yesterday I found out that a similar library was created some years ago. But it did not support flash string for printf formatting string. And it is not in Library Manager.

  sb.print(F("HEX of char: "));
  sb.println(c, HEX);

HEX of char 43

Either the output is a cut and paste error, or the class has a problem.

PaulS:

  sb.print(F("HEX of char: "));

sb.println(c, HEX);



Either the output is a cut and paste error, or the class has a problem.

try again

Juraj:
try again

Try what again?

PaulS:
Try what again?

processing the input :slight_smile:

I was pointing out that there are an apparent discrepancy between the code and the output. That is either because the output was not from the posted code or because the posted code is doing something wrong.

It is up to you to explain which is true, and, if it was a problem with the library, to say that and to post the corrected output.

I'm not going to use a library that has apparent bugs.

the : ?

sorry, the output was not from the posted code

I thought you were questioning the hex value

sorry, the output was not from the posted code

OK.

Why not? It would certainly be better if they matched.

PaulS:
OK.

Why not? It would certainly be better if they matched.

publishing a library with a documentation is not an easy task. at writing the docs one sees shortcomings and returns to code, then back to examples and docs. then is the moment of publishing and the again some small fixes.... and not enough free time to triple check everything :slight_smile:

@pert, /dev made a BufferPrint library, but I fear that the template construct makes a copy of the class for each used size. it is good with always the same buffer size in a sketch

I fear that the template construct makes a copy of the class for each used size.

Not necessarily. I have seen the template arguments turn into instance members, with one copy of code. I don't recall if I looked at NeoBufferedPrint, but I think the compiler probably will do that. That class adds the "flush when full" concept to a fixed-size buffer.

I need to add a base class, really, that does what you have offered. Then NeoBufferedPrint can "derive" from that class.

You might want to look at pyro_65's PrintEx library. Much more complete.

the PrintEx has not solved serious issues and the formatting string in printf can't be F()

I made my minimal StreamLib. Should I publish it to Library Manager?

I say yes to Library Manager addition. I'd like to see Library Manager become a comprehensive catalog of all Arduino libraries. Even though it already has >1400 libraries I still end up doing a Google search to discover libraries because there are a lot still not in the Library Manager index. I also really like the automatic notifications of new releases of my installed libraries that are in the index.

That said, I haven't added my libraries to Library Manager. I probably should do it, but I think I'm probably about the only person using them (and for good reason). My personal feeling is that, as long as the library author has made a reasonable effort to write working code and provide sufficient documentation, every library should be added to the index. I'm not sure whether that sentiment is shared by the rest of the Arduino community or if there is some additional standard of general usefulness that should be expected from libraries added to the index. Certainly that standard would need to be self-imposed since there is no way for the Arduino team to vet the quality of libraries that are submitted for addition beyond the automated check of the metadata and folder structure. Maybe the solution would be to offer an interface that shows usage statistics, ratings, and reviews of a library.