Using String as Stream?

I have found this library for my RTC DS3231 device and I like it very much except I would like to the output of the Print... functions to be returned as a string instead of being printed in Serial stream

Is there a way to declare a String variable as a Stream and use it in those calls or a way to declare a Stream variable and then convert that to a string/char[] buffer.

The data in the end will be either displayed on a UTFT controlled LCD screen and/or transmitted via Ethernet shield hence the need to it to be stored in a local variable of sorts.

I know I could fork the library and convert the functions to return the string instead, but I'd like to see if I can avoid this first.

Just Create a subclass of stream to capture the print call in a String, and pass an instance of that class to the library instead of a HardwareSerial or SoftwareSerial. Then the data ends up in an object you control.

Is there a way to declare a String variable as a Stream and use it in those calls or a way to declare a Stream variable and then convert that to a string/char[] buffer.

No and no.

Hand-waving doesn't cut it on this forum. You need to be specific about which method(s) do(es) something in a way that you want to use in a different way.

You can use my PrintEx library to achieve this. You can download it from the library manager within the IDE.

It contains an interface called GString which will wrap a char array with a Print interface. This essentially allows you to use print functions on RAM rather than sending it to Serial for example.

However it only implements a Print interface, not a Stream.

There is another tool called PrintAdapter which will convert a Print object into a Stream object. With these combined, you can then pass the adapter object to any function expecting a Stream object.

It sounds complicated, but check the code below and it'll hopefully be quite straight forward.

#include <PrintEx.h>

void setup() {

  Serial.begin(9600);

  char buffer[50];               //Create buffer to store output.
  GString str = buffer;          //Wrap the buffer in a GString, making it printable.
  PrintAdapter streamer = str;   //Convert a Print object to a Stream object.

  func( streamer );              //Can now call a function expecting a stream.
  
  Serial.print(str);             //Print the GString data.

}

//A function expecting a Stream object.
void func( Stream &stream ){
  stream.print( "foobar" );
}

void loop() { /* No loop code */ }

The code above prints out the GString result to Serial. However if you want to use the data stored in buffer directly you'll need to null-terminate the string it contains.

Once you are done with the GString, call end() to null terminate the buffer, then you can do what you like with the raw data.

//Instead of: Serial.print(str); 

str.end();  //Null terminate the wrapped array 'buffer'.

Serial.print(buffer);  //Use the null terminated char array directly.

If you want to use this, but have questions/can't get it working. Just post some code with a description of your problem and I'll help you out.

Thank you pYro_65 that was indeed what I needed.

No worries, this is one of many reasons why I have my library. Glad it can help you.