PString

A Lightweight String Class for Formatting Text

Note: PString 3 is now Arduino 1.0 compatible.

Since Print was introduced with Arduino 0012, several classes, including HardwareSerial, LiquidCrystal, Ethernet Client/Server, and my own NewSoftSerial, have been written to leverage its text rendering engine.  But getting formatted text to output devices not in this short list still requires either writing custom code or turning to expensive alternative solutions like sprintf().

PString (“Print-to-String”) is a new lightweight Print-derivative string class that renders text into a character buffer. With PStrings, you can use the Print renderer for any device, even those that do not directly support Print-style text formatting, by first “printing” to a string.

In its simplest use case, you deploy an “on-the-fly” constructor to format text:

char buffer[30];
#define pi 3.14159
PString(buffer, sizeof(buffer), pi);

This code uses Print’s float rendering functions to generate the string equivalent of pi into buffer.

Since PString inherits from Print, PString objects can do everything that other Print-derived classes do:

<code>char buffer[50];
PString mystring(buffer, sizeof(buffer));
char name[] = "Joe";
int age = 45;

mystring.print("Hi, my name is ");
mystring.print(name);
mystring.print(" and I am ");
mystring.print(age);
mystring.println(" years old.");

This generates the expected sentence in buffer the same as if you had printed to the Serial port.

Other member functions

PString is a fairly minimal string class. It can report its length and capacity and give const access to its internal string buffer:

Serial.print(str.length());
Serial.print(str.capacity());
Serial.print(str);

You can reuse a string by calling its begin() function. This effectively resets the position in the buffer where the next printed text will go:

str.print("Hello");
str.begin();
str.print("World");
// str contains "World" here

Operators

PString provides three operators for assignment, concatenation, and equivalency test:

char buffer[20];
PString str(buffer, sizeof(buffer));
str = "Yin"; // assignment
str += " Yang"; // concatenation
if (str == "Yin Yang") // comparison
{
  Serial.println("They are equal!");
}

Runtime safety

PStrings do not “own” their own buffers. Instead, they rely on preallocated static buffers that are passed in at the point of construction. PStrings never allocate memory dynamically, even when the result of a print(), assignment, or concatenation operation would seem to exceed the current buffer’s size. In these cases, the excess data is simply discarded and the string correctly terminated.

Because of these constraints, PStrings can make three key guarantees:

  • they will never cause a buffer overflow
  • a string’s buffer will always be valid memory, i.e. the original buffer
  • buffers will always contain valid (i.e. NULL-terminated) C string data.

Download

The latest version of PString is PString3.zip.

Revision History

Version 1 – initial release
Version 2 – include support for inline renderings with modifiers HEX, OCT, etc. (and eventually float precision)
Version 3 – Arduino 1.0 compatibility

Resource Consumption

PString objects consume 8 bytes of memory during their lifetimes. Depending on what features are used, #including the PString library usually adds only 100-600 bytes to a program’s size.

All input is appreciated.

Mikal Hart

Page last updated on July 3, 2013 at 7:42 pm
60 Responses → “PString”

  1. gus smith

    1 month ago

    I’m new to Arduino, probably a noob question. I would like to use PString in a custom class like this:

    class MyClass
    {

    public:
    MyClass();

    private:
    char _buffer[100];
    PString buffer(_buffer, sizeof(_buffer));

    };

    This gives the error: “C++ requires a type specifier for all declarations”

    How can I solve this or is this not doable?

    cheers,
    Gus


  2. Mikal

    1 month ago

    @Gus, make sure you #include , and if this custom class is in a secondary file, put #include in the main sketch as well. Let me know if that solves your problem.


  3. Yuzee

    1 month ago

    Hello!!

    Could it support Arduino 1.5.3 for Galileo?

    Error compiling show this message:

    Arduino: 1.5.3 (Windows NT (unknown)), Board: “Intel® Galileo”

    In file included from PString.cpp:20:0:
    PString.h:34:16: error: conflicting return type specified for ‘virtual void PString::write(uint8_t)’
    In file included from PString.h:23:0,
    from PString.cpp:20:
    C:\Users\stone\Desktop\arduino-1.5.3\hardware\arduino\x86\cores\arduino/Print.h:48:20: error: overriding ‘virtual size_t Print::write(uint8_t)’

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.

    How could I solve this problem.

    thanks


  4. Mikal

    3 weeks ago

    Hi Yuzee–

    Thanks. I’ll fix this soon.

    M

6 Trackbacks For This Post
  1. Introducing PStrings « Arduiniana

    [...] Check out the new PString class. [...]

  2. ka1kjz.com » Twittering Arduino Completed

    [...] actual text for the tweet, the Arduino has very limited string manipulation functions.  But the PString library by Mikal Hart proved to be just what I [...]

  3. Arduino net connected clock tells weather not time

    [...] third party libraries were used; PString to handle parsing the incoming website, Flash for memory management, and Streaming for easier [...]

  4. Arduino and Windows HyperTerminal | Binglong's space

    [...] is a text string with an ending CR(Carriage Return, 0x0d), so is any reply from the board. Actually PString can be used to format the reply (or an active notification from board) easily. Messenger can be [...]

  5. Buffering sensor data to an I2C eeprom. | An Arduino Based Underwater Sensor Pod

    [...] days of heavy lifting later…I had cobbled together this script, using PSTRING to to dramatically simplify the concatenation of the sensor data into a 28 byte long char buffer [...]

  6. Using a cheap $3 DS3231 RTC & AT24C32 EEprom from Ebay | An Arduino based underwater sensor project

    [...] me be really lazy on the coding and just block write ANY numbers or characters that I PSTRING’d together before I send that buffer variable to the eeprom page writing code.  This flexibility [...]

Leave a Reply