Question about the array compare

Hi all.
The program fragment below try to compare two arrays and print some thing if true.

char *SDFoldersB0[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};  // 
char *CMDword[20] = {};
char *currtweekDAY[14] = {}; 
char timeStringWK[20];

strftime(timeStringWK, 20, "%A", timeinfo); // from RTC date got the current day of the week day; 
currtweekDAY[0] = timeStringWK;  // sign the day to 

void currentDAY_compare() {

  for (int i = 0; i < 7; i ++) {
    if (currtweekDAY[0] == SDFoldersB0[i]) {  // 

      currentDAYmark = i;

      Serial.print("currentDAYmark =");   
      Serial.println(currentDAYmark);

    }
  }
}

the condition never true and never print any thing out.
if manually set: currtweekDAY[0] = "Friday"; works well.
got: currentDAYmark =4, i = 4;

why so?

First, print out the two things you are trying to compare. Maybe print them between < > so you can be sure you seeing the right stuff.

Next, look into the function strcmp(). You can't just use '==' to test two null terminated character arrays for equality.

You're gonna skip the first step, aren't you?

a7

1 Like

I did printed: currtweekDAY[0] and got = Friday; printed out SDFoldersB0[i] got 7 week days.
I'll test strcmp () .
Thanks.

modified again for the progress, this way got result, I need do 7 times for week days, any way to simple it?

void currentDAY_compare() {

  int result = strcmp(currtweekDAY[0], "Monday");
  if (result == 0) {

    currentDAYmark[0] ="1";

    Serial.print("169currentDAYmarkM =");   //print: currentDAYmark =100, not calculated
    Serial.println(currentDAYmarkM);

  }

 result = strcmp(currtweekDAY[0], "Tuesday");
  if (result == 0) {

    currentDAYmark[1] = "1";

    Serial.print("169currentDAYmarkM =");   //print: currentDAYmark =100, not calculated
    Serial.println(currentDAYmarkM);
  }
}

........

1 Like

Thanks.

No no no. You have a common pattern. Rather than cut/paste/edit it to do 6 more things, put it in a function or at least in a for loop.

I haven't tacked your path, but stop,if you aren't up to speed on functions and arrays… they are key to getting things done.

since you already have, conveniently, the strings:

char *SDFoldersB0[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};  

you can do stuff like

  int curretnDay = 100;

   for (int ii = 0; ii < 7; ii++) {
    int result = strcmp(currtweekDAY[0], SDFoldersB0[ii]);
    if (result == 0) {

      curretnDay = ii;

      Serial.print("169currentDAYmarkM =");   //print: currentDAYmark =100, not calculated
      Serial.println(curretnDay);

      break;  // it was this day, so no need to look at the rest of the week
    }
  }

  if (curretnDay == 100) Serial.println("...currentDAYmark =100, not calculated");

I used an int instead of your character string assignment as I did not take time to see what you did that.

I could not test what I wrote, but I hope you see the idea.

a7

1 Like

Thank you alto777.

Don't know what reason, may cause of the currtweekDAY[0] is come from: timeStringWK; ? as: currtweekDAY[0] = timeStringWK;
the compare: if (currtweekDAY[0] == SDFoldersB0[i]) never works.

but if I manually set: currtweekDAY[0] = "Friday"; , the above compare work well.

its why I got rid of the week day array SDFoldersB0[i] and just manually use strings like "Monday", "Tuesday" .... to do the compare, this way got what I need, just a foolish method.

It is hard to fix outside the context of a complete sketch.

Either post all your code, or better, a little tiny sketch you are writing to experiment with this kind of stuff… that gives you a compiler error or doesn't do what you think it should or want it to.

And perhaps describe carefully what you are trying to accomplish. You can def use an array of days of the week, you do not have to resort to "Monday" and copy pasting code six times!

a7

1 Like

Well, this code illustrated my question.

#include <WiFi.h>
#include "time.h"

const char* ssid     = "vvv";
const char* password = "vvvv";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = -18000;
const int   daylightOffset_sec = 3600;

char *currtDAY[7] = {};  //
char *currtweekDAY[14] = {};
char *SDFoldersB0[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};  // list all folders on SD, and vary based on which app, DFRobot used 'NOTEs';

int  CMDDAYmark = 100;

void setup() {
  Serial.begin(115200);

  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");

  // Init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();  //

  NPTdatetime_7dayAdj();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop() {
  delay(1000);
  printLocalTime();
}

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void NPTdatetime_7dayAdj() {

  time_t now = time(nullptr);
  char timeString[100];
  char timeStringWK[20];

  tm *timeinfo;
  for (uint8_t dayAdj = 0; dayAdj < 7; dayAdj++) {
    timeinfo = localtime(&now);
    //  strftime(timeString, 100, "%A, %B %d %Y %H:%M:%S %Z", timeinfo);

    if (dayAdj == 0) {   //
      strftime(timeStringWK, 20, "%A", timeinfo);
      currtweekDAY[0] = timeStringWK;
    }

    now += 86400;
  }
  delay(1000);
  currentDAY_compare();
}

void currentDAY_compare() { // CMDword[0] = "Monday";

  for (int j = 0; j < 7; j ++) {
    if (currtweekDAY[0] == SDFoldersB0[j]) {
      CMDDAYmark = j;

      Serial.print("100SDFoldersB0[j] =");
      Serial.println(SDFoldersB0[j]);

      Serial.print("103 j =");
      Serial.println(j);

    }
  }

  currtweekDAY[0] = "Friday";
  for (int k = 0; k < 7; k ++) {
    if (currtweekDAY[0] == SDFoldersB0[k]) {
      CMDDAYmark = k;

      Serial.print("114SDFoldersB0[k] =");
      Serial.println(SDFoldersB0[k]);

      Serial.print("117 k =");
      Serial.println(k);

    }
  }
}

Sry, lazy.

I know I could read read read this code and then maybe be able to read your mind, but it would be better if you could just spare a few words and say what you are trying to accomplish with this sketch, or exactly, if it is just for illustrative purposes, what it does that it should not, or does not do that it should.

a7

1 Like

ya.
all code do two things:

  1. get the current day date of weekday, say today got: (timeinfo = localtime(&now);) = Saturday;
    and set it to: currtweekDAY[0] = timeStringWK; (= Saturday);

  2. use this currtweekDAY[0] compare with the week day array which included 7 week days, to get to know which week day match currtweekDAY[0] .

You already have the tm struct timeinfo, timeinfo.tm_wday will tell you the day of the week (Sunday is 0).

currtweekDAY[0] now contains a pointer to timeStringWK, which will not change regardless of the text stored in timeStringWK.

You are comparing pointers, currtweekDAY[] points to timeStringWK, SDFoldersBO[j] points to the literal strings that were declared when you initialized the SDFoldersBO array. Those will never be equal.

As was stated previously, you need to use strcmp() to compare the strings pointed to by the pointers, although there is no need to do that since you already know the numeric value for the day of the week.

2 Likes

sorry I have to modify this reply. I didn't totally understood david_2018's post #12 then of:

BY: currtweekDAY[0] = timeStringWK;

strftime(timeStringWK, 20, "%A", timeinfo); this line never work. nothing printed;

after manually set: currtweekDAY[0] = "Friday";

strftime(timeStringWK, 20, "%A", timeinfo); this line works now.

If you insist on doing this with strings, then try this:


void currentDAY_compare() {
  for (int j = 0; j < 7; j ++) {
    if (strcmp(currtweekDAY[0], SDFoldersB0[j]) == 0) {
      CMDDAYmark = j;

      Serial.print("100SDFoldersB0[j] =");
      Serial.println(SDFoldersB0[j]);

      Serial.print("103 j =");
      Serial.println(j);

    }
  }
}

Although it is much simpler to just do something like this:

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.print("numeric day of week: ");
  Serial.println(((timeinfo.tm_wday) + 6) % 7); //convert start of week from Sunday to Monday
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
1 Like

Thank you david_2018.
I modified my reply #13 with a sorry there....

the reason I like to use the string compare is because there are some calculations based on that compare, let's say it take correntDAY as 0, and the timeinfo.tm_wday take Sunday as 0. I may modify my calculation for that.

I just want to be sure you understand and are properly exploiting the difference between these two variables:

char *currtweekDAY[14] = {};


char timeStringWK[20];

a7
1 Like

Thank.
I can just understand that the char *currtweekDAY[14] = {}; means pointer, and
char timeStringWK[20]; means char string.

You've used currtweekDAY[0], what are your plans for the other thirteen pointers to char in that array?

a7

1 Like

actually, at the beginning, I designed it as: char *currtweekDAY[2] = {}; , some others just as:
char *currtweekDAY[1] = {}; , the purpose is to use its pointer only for one, its why here is:
currtweekDAY[0] .
I do have : char *SDFoldersB0[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; multi pointers, works as compare base like above.
I known there must be smart way there.

Thanks.

If you want one pointer to char, declare it. You don't need an array of them of which you ignore all but one:

char *pointerToChar;

Use it like you do currtWeekDSY[0];

      pointerToChar = timeStringWK;

Of course name it something better.

Given, however, that your first problem was comparing string arrays improperly, I am suspicious that you just started improvising and threw stuff at the compiler until it shut up.

You probably used '=' to try and copy character arrays, we would have told you that like strcmp(), copying needs to be done differently and turned you on to strcpy(),

This is not an effective development path.

You don't need Strings or strings or pointers to char, you've been offered the simple solution of dealing with the day of the week as a number, unless and until you need to present it to humans, for which

// assume int dayNumber is from the RTC
  Serial.println(SDFoldersB0[dayNumber]);

will work fine. I might name that SDFoldersB0 something like dayNames. You do you on the naming stuff.

There are a handful of standard functions for working with character arrays. They are not as easy to use as Capital S Strings, but you can figure it out.

You just have to take a break from getting them to work for you in the context of a real project and find some learning materials and start as if you know even less than you think.

a7

1 Like

Thank you alto777.
I appreciate your detailed help and it's exactly my shortage.
Have a great day.