New at strings - Why is this so hard?

Why does this:

const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
//
// thisMon = 4
//
Serial.print(*months[thisMon - 1] & '\0');

Blow up? It compiles, but seems to cause a memory puke.

Why the + '\0'? "Jan", "Feb" etc are already nul terminated.

months is an array of c-strings; you pick an element by using months[index], not by using *months[index]. Contrary to Strings (capital S), c-strings are pointer and adding something to a pointer is different from adding (concatenating) something to a String.

So your serial print should be

Serial.print(months[thisMon - 1]);
Serial.print(months[thisMon - 1]);

It compiles but won't run. It causes VERY erratic behavior and screws up an unrelated section of code that recovers if I comment that ONE LINE out.

Before you ask, here is my void loop()

Search for "months[thisMon"

const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const char *dows[]   = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
//
// Fall into runtime
//
void loop() 
  {
  Time t = rtc.time();  // Poll clock
  // 
  // Let LED matrix running until eom
  // 
  if (!lmd.updateTicker()) lmd.stopTicker();  //Stop at end
  //
  // Fast execution items lead
  //
  // We need to watch the RTC and trigger when the seconds change
  //
  // hard poll IR while waiting
  //
  while (thisSec == lastSec)  // Wait for clock to tick
    {
    t = rtc.time();         // Get latest
    thisHr    = t.hr;
    thisMin   = t.min;
    thisSec   = t.sec;
    thisDate  = t.date;
    thisMon   = t.mon;
    thisYr    = t.yr;
    thisDay   = t.day;
    //
    // IR remote code is big switch.
    // There are 21 different buttons with unique responses
    //
    // IR Remote needs to be shielded from other light sources
    // Umm dunno how fast we should poll this. Its fast polling now. 
    // but we might need to slow it down
    //
    // We'll use the pot to control the matrix brightness
    // when not othrewise busy
    //
    if (dimMode) lmd.setIntensity(analogRead(Wiper) / 64);
    //
    CheckIR();    // Does 21 different functions
    //
    // Update status lights in real time
    //
    digitalWrite(TL_R, digitalRead(K2));    // Reminder that power relay is on is RED
    digitalWrite(TL_Y, AlarmSet);           // Show amber if alarm is set
    //
    if (!lmd.updateTicker()) lmd.stopTicker();  //Stop at end
    //
    }
  //
  // New second passes
  //
  digitalWrite(TL_G, !digitalRead(TL_G));   //Toggle heartbeat on second
  //
  lastSec = thisSec;      // Note this second
  //
  // Alternate : and . as tic-tok on 8x8x4 matrix
  //
  colon == ":" ? colon = "." : colon = ":";
  //
  // Display time
  //
  formTime();
  //
  // Ok, from here on out we have our activities.
  // Each looks at the time and does their thing
  //
  // Check to see if the coffee pot is still on after an hour
  // if so, turn it off
  //
  int tempHr = alarmHr + 1;
  if (tempHr > 23) tempHr = tempHr - 24;  //Compensate for past midnight
  //
  if ( ( (tempHr   ==  thisHr)   && 
         (alarmMin == thisMin) ) && onbyAlarm)
    {
    digitalWrite(K2, LOW);    //Turn off
    onbyAlarm = false;
    K2State   = false;
    //
    Serial.print("K2 Auto off: " + String(tempHr) + " " + String(thisHr) );
    blip();                                 // Little noise to get you to look
    waitTicker(F("Aux relay auto off"));    // Let user know
    formTime();                             // Show time
    chime(3);                               // Different
    }
  //
  // Check for alarm time being set
  //
  if (  (alarmHr  ==  thisHr) && 
        (alarmMin == thisMin) && 
        (thisSec  ==       0) &&
         AlarmSet)
    {
    //
    // Kick on coffee pot relay - we should turn this
    // off automatically  after an hour
    //
    blip();                     // prealarm noise
    digitalWrite(K2, HIGH);     // Load comes on with alarm
    K2State   = true;           // Internal state flag - Y not read IO?
    onbyAlarm = true;           // Alarm turned us on
    //
    // Wakey Wakey!
    //
    waitTicker(F("Wakey! Wakey!"));
    formTime();  //Show time
    //
    sloChime(10);
    if (!aborted)
      {
      waitTicker(F("Get up & PEE! The world's on FIRE!"));
      formTime();  //Show time
      //
      sloChime(10);
      if (!aborted) 
        {
        waitTicker(F("Outta bed, sleepy head!"));
        formTime();  //Show time
        sloChime(10);
        }
      //
      }
    //
    }
    //
    // Show temp at 1/4 past minute
    //
    if ( (thisSec == 15) && !lmd.updateTicker() )
      {
      Read_DHT();       // Read temp/humidity
      tempFC ? lmd.ticker(String(f, 1) + "F", scrollRateMs) : 
               lmd.ticker(String(c, 1) + "C", scrollRateMs);
      //
      }
    //
    // Show Date at 30 - add month names
    //
    if ( (thisSec == 30) && !lmd.updateTicker() ) 
          //
          Serial.print(months[thisMon - 1]);
//          tmpStr = String(*months[thisMon - 1] & '\0');
//          tmpStr += "\0";
//          //
//          lmd.ticker(tmpStr + 
//
          lmd.ticker(String(thisMon) + 
          "/" + String(thisDate) + 
          "/" + String(thisYr).substring(2), scrollRateMs);
    //
    // Show RH at 3/4 of minute - use reading from :15
    //
    if ( (thisSec == 45) && !lmd.updateTicker() )
          lmd.ticker(String(h, 0) + "% RH", scrollRateMs);
  //
  // Min = 0 & sec = 0 = hour strike
  //
  if ( (thisMin == 0) && (thisSec == 0) )
    {
    blip();               //Little noise to make you look
    waitTicker(F("Cuckoo! Cuckoo!"));
    formTime();           // Show time
    //
    tmp = thisHr;         // Time from globals
    //
    if ((tmp > 12) && (clockMode12)) tmp = tmp - 12;   //Civilian time
    //
    // Start and end times need to be selectable
    if ((thisHr >= chimeOnHr) && (thisHr <= chimeOffHr)) // Only chime 11A-11P per swmbo
      {
      sloChime(tmp);    //Change to MP3 "Bong" when I get it installed
      }
    //
    }
  //
  // Later in execution overrides time display above
  //
  if ((thisHr == 16) && (thisMin == 20) && (thisSec == 0))
    {
    blip();     //Little noise to make you look
    waitTicker(F("It's 4:20! SMOKE BREAK!"));
    formTime();           // Show time
    sloChime(4);
    //
    waitTicker(F("It's 4:20! Time to roll a fattie!"));
    formTime();           // Show time
    sloChime(2);
    }
  //
  if ((thisHr == 20) && (thisMin == 40) && (thisSec == 0))
    {
    blip();     //Little noise to make you look
    waitTicker(F("It's 8:40! TIME TO SMOKE!"));
    formTime();           // Show time
    sloChime(8);
    //
    waitTicker(F("It's 8:40! Time to Relax!"));
    formTime();           // Show time
    sloChime(4);
    }
  //
  // Log data on 1/4 hour
  //
  if ( ((thisMin ==  0) || 
        (thisMin == 15) || 
        (thisMin == 30) || 
        (thisMin == 45)) && (thisSec == 0))
        append("");   // Append to log
  //
  // Midnight data dump and reset
  //
  if ( (thisHr == 0) && (thisMin == 0) && (thisSec == 0) )
    {
    logIt();    // Make log entry with days data
    }
  //
  }     // End of LOOP

Instead of displaying the time it starts to scroll the date for no apparent reason and resets and repeats after showing three chars. Comment that line out and sanity is restored. The remote is still working, but just the scrolling LED matrix takes a nose dive. As the program initializes it scrolls a couple of messages in Setup without issue.

I've got NO CLUE.

Here is what I do instead, and it works for me. (Hint: try reading it vertically.)

Serial.print("BJFMAMJJASOND"[thisMon]);
Serial.print("aaeapauuuecoe"[thisMon]);
Serial.print("dnbrrynlgptvc"[thisMon]);

I'm trying to format a date string "Apr/10/22" I've got all the pieces but can't seem to figure out how to get a string to work in the .ticker() function.

THIS WORKS:

#include <LG_Matrix_Print.h>      // LED matrix - test works
...
const int MISOLED   = 50;   // Needed for 8X8 LED matrix comms
const int MOSILED   = 51;
const int SCKLED    = 52;   // builtin LED & SPI clock
const int CSLED     = 53;   // 8x8 x4 LED matrix CS line
//
...
const int segments = 4;
//
LG_Matrix_Print lmd(segments, CSLED);
...
lmd.ticker(String(thisMon) + 
  "/" + String(thisDate) + 
  "/" + String(thisYr).substring(2), scrollRateMs);

and it shows:

4/10/22

But I want:

Apr/10/22

What happens if you instead try this?
(String(monthList).substr[(thisMon*3)-3], 3)
For that you will need: String monthList = "JanFebMarAprMayJunJulAugSepOctNovDec";

EDIT: corrected an off-by-one bug

I thought of that, but why is what I'm trying wrong? It seems like it should be trivial. Here's an array, print element 'n'.

Because you didn't tell it to print element 'n'
What you instead told it to do was print the index 'n'.

Ok, but what's the FIX?

This works fine...


const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};


void setup()
{
  Serial.begin(115200);
  while (!Serial);
  
  for (int x=0; x<12; x++)
  {
    Serial.println(months[x]);
  }
}

void loop()
{
  
}

*months[] is an array of pointers. Each pointer points to a char array in memory, terminated by 0x00. To access each char array you simply reference months[ x ] (NOT *months[ x ]).

I pasted in:

  for (int x=0; x<12; x++)
  {
    Serial.println(months[x]);
  }

a the bottom of Setup() and it worked as expected. But when I add:

Serial.println(months[thisMon]);

In the middle of my loop() all hell breaks loose on my display! I have no idea. I'm at 20% program and 60% ram.

The remote triggers functions and the unit responds correctly, just the matrix display screws up!

Add this line so you can see what thisMon contains...

Serial.println(months[thisMon])

thisMon can only be 0-11 otherwise the index is out of range. For your example it might be more like:

  for (int x=1; x<=12; x++)
  {
    Serial.println(months[x - 1]);
  }
Serial.println(months[4]);

crashes the same way.

FOUND IT

!@#$%^&* missing {}!

The statement had started as a single line IF (no {} needed), not being smart at C++ when I spread it out into multi-line the compiler got as confused as I was. Put in {} pair and all is better!

TYVM to all who replied so quickly! It was a great help to let me think it thru with a sounding board. I knew it had to be something STUPID on my part.