Go Down

Topic: New library CStringBuilder to print content to a c-string (Read 432 times) previous topic - next topic

Juraj

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).

Code: [Select]
#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

Code: [Select]
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

pert

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.

Juraj

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.

PaulS

Code: [Select]
  sb.print(F("HEX of char: "));
  sb.println(c, HEX);


Quote
HEX of char 43
Either the output is a cut and paste error, or the class has a problem.
The art of getting good answers lies in asking good questions.

Juraj

Code: [Select]
  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

PaulS

The art of getting good answers lies in asking good questions.


PaulS

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 art of getting good answers lies in asking good questions.

Juraj

the : ?

sorry, the output was not from the posted code

I thought you were questioning the hex value

PaulS

Quote
sorry, the output was not from the posted code
OK.

Why not? It would certainly be better if they matched.
The art of getting good answers lies in asking good questions.

Juraj

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 :-)

Juraj

@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

-dev

Quote
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.
Really, I used to be /dev.  :(

Juraj

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

Juraj

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

Go Up