Hello, as an exercise in learning C++ and decent OOP in C++, I'm creating a class that I can use to easily manipulate specified areas on an OLED display. I could create a new print area, set the value (string or int), then modify it, movie it, etc, as needed.
The issue I'm having is how I store the string (char, not String), and how I modify it by appending/prepending values to it.
Here are the sketch files I've created for this post (removed the code that wasn't relevant:
I'm executing this on a new Arduino Nano Every (not sure if that matters).
OledText.hpp:
#pragma once
#ifndef OLED_TEXT_H
#define OLED_TEXT_H
// Including "settings" here just to make sharing it simpler
constexpr unsigned int VALUE_TYPE_NONE = 0;
constexpr unsigned int VALUE_TYPE_CHAR = 1;
constexpr unsigned int VALUE_TYPE_INT = 2;
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>
#include <ArduinoSTL.h>
//#include <map>
#endif
class OledText {
public:
char *printerVal;
Adafruit_SSD1351 * OLEDHandler;
OledText(Adafruit_SSD1351 &OLEDHandler);
// Set/update the print containers display value to a string, then display it
void print(char charValue[]);
//void print(char *charValue);
//void print(char charValue[25]);
// Set/update the print containers display value to an integer, then display it
void print(long intValue);
// Function to re-print whatever value/type is saved (will be useful if the
// printed text needs to be "reloaded" for various reasons)
void print();
void prepend(char *prependTxt);
//void prepend(char prependTxt[25]);
//void prepend(char prependTxt[]);
};
OledText.cpp:
#pragma once
#include "OledText.hpp"
OledText::OledText(Adafruit_SSD1351 &OLEDHandler) : OLEDHandler (&OLEDHandler) {}
// If user were to set/change the printer to a CHAR...
void OledText::print( char charValue[] )
{
this->printerVal = charValue;
//strcpy(this->printerVal, charValue);
this->print();
}
// User provides a new NUMERICAL value, store it as a char
void OledText::print( long intValue )
{
char cstr[16];
itoa( intValue, cstr, 10 );
this->printerVal = cstr;
this->print();
}
// This would print the stored value in the specified area, but for this forum
// post, I'm just outputting the value to serial
void OledText::print()
{
std::cout << this->printerVal << std::endl;
return;
}
// User wants to prepend (or append, in a diff function) a string
// to the beginning of the char value..
void OledText::prepend( char prependTxt[] )
{
if ( strlen( this->printerVal ) == 0 )
{
// Nothing to append anything to, just switch to a regular print
return this->print( prependTxt );
}
char newCharValue[ strlen(prependTxt) + strlen(this->printerVal) +1 ]; // add +1 for end?...
strcpy( newCharValue, prependTxt );
strcat( newCharValue, this->printerVal );
// Print the new char (with the prefix prepended)
this->print( newCharValue );
}
Char_Prepend_Sketch.ino:
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>
#include "OledText.hpp"
Adafruit_SSD1351 oled = Adafruit_SSD1351(128, 128, &SPI, 10, 9, -1 );
OledText Greeting(oled);
void setup() {
Serial.begin(115200);
//
// Bunch of irrelevant Adafruit_SSD1351 init code removed.
//
Serial.print("\nExpected output: 1234\n\t-> ");
Greeting.print(1234);
Serial.print("\nExpected output: World\n\t-> ");
Greeting.print("World");
Serial.print("\nExpected output: Hello World\n\t-> ");
Greeting.prepend("Hello ");
Serial.print("\nExpected output: Hayy, Hello World\n\t-> ");
Greeting.prepend("Hayy, ");
Serial.print("\nExpected output: Goodbye\n\t-> ");
Greeting.print("Goodbye");
Serial.print("\nExpected output: Goodbye\n\t-> ");
Greeting.print();
}
void loop(){}
Basically, I should be able to create the OledText instance Greeting, then use Greeting.print("World") to set the local variable this->printerVal to World, then use Greeting.prepend("Hello, ") to prepend the Hello to the beginning of printerVal, making it Hello, World.
And that part actually works. It's when I prepend another value onto the end of it that it seems to break.
Here's the output of the above code (which also outputs what I expect to see):

I have a feeling that maybe the fact the class member printerVal is a pointer, I just read on The Evils of Arduino Strings | Majenko's Hardware Hacking Blog that pointers strings shouldn't ever be modified, and ideally they should always be constants. But I need to be able to modify this, and I've tried passing it by reference. I also tried changing it to just char printerVal[]; but then I got an error about unbound arrays needing to be last in the class, so I moved it there and got some other errors.
I'm sure there are a thousand issues with the above code, but only recently started learning C++ (or Arduinos version of it), so don't judge it too harshly, lol. I do plan on reading the C book that Dennis Ritchie wrote (sooner rather than later, ideally).
Thanks in advance!
-J
