Why cant I compare arrays?

Hi everyone, I'm having trouble with my code.

So, I have a joystick connected to my arduino nano and I wrote a code that detects the direction of the joystick (up=N,down=S,left=O,right=E), and verifies if it corresponds to the right sequence.

//Arduino pin numbers
const int SW_pin = 2; //digital pin connected to switch output
const int X_pin = 0; //analog pin connected to x output
const int Y_pin = 1; //analog pin connected to y output
int newCode = 0; //Detects when the Switct button is pressed
const int numSeq = 6;//number of chars in the Sequence
const char corSeq[numSeq] = "NSEONS";//Sequence
char Seq[numSeq];


void setup() {
  pinMode(SW_pin, INPUT);
  digitalWrite(SW_pin, HIGH);
  Serial.begin(115200);
}

void reset(){
  newCode=0;
  Seq[numSeq] = {""};
}
void loop () {
  if(digitalRead(SW_pin) == 0){
      newCode++;
  }
  if(newCode==1){
    Serial.print("Podes Começar");
    Serial.println();
    newCode=0;
    int i=0;
    while(i<numSeq){
      if(analogRead(X_pin)==0){
        Seq[i] = 'S';
        Serial.print(Seq[i]);
        i++;
        delay(500);
      }
      else if(analogRead(Y_pin)==0){
        Seq[i] = 'O';
        Serial.print(Seq[i]);
        i++;
        delay(500);
      }
      else if(analogRead(X_pin)==1023){
        Seq[i] = 'N';
        Serial.print(Seq[i]);
        i++;
        delay(500);
      }
      else if(analogRead(Y_pin)==1023){
        Seq[i] = 'E';
        Serial.print(Seq[i]);
        i++;
        delay(500);
      }
      
    }

    if(strcmp(Seq, corSeq)==1){
      Serial.print("Good!");
    }
    else{
      Serial.print("Try again");
      Serial.println();
      reset();
    }
  }


}

Every part of the code is working, unless the last part, where I compare the sequence introduzed by the user with the right one. I keep introducing the right one and it keeps telling me that it's wrong. I also try printing both and it was the same content and type(char[6]).

Can someone PLEASE help me?

Hello

strcmp returns 0 when the strings are equal.

But you have another error in your code.

const int numSeq = 6;//number of chars in the Sequence
const char corSeq[numSeq] = "NSEONS";//Sequence
char Seq[numSeq];

"NSEONS" is a null-terminated char array. So your array is too small to hold 7 characters. strcmp will only compare null-terminated char arrays.

And another error here : Seq[numSeq] = {""}; you are writing outside of the array..

2 Likes

If you turn on all compiler warnings in the preferences and set the verbose mode, then the compiler will tell about the problems that user guix writes about.

As an aside, strcmp is intended to compare text to determine which would be first, like when sorting for a dictionary. (And case matters: in ASCII, all uppercase letters come before all lowercase letters.)

Consider if you had two integer variables, a and b. If you subtract them: (a - b), then the result is

  • zero if they are the same
  • a positive value if a is greater than, or comes after, b
  • a negative value if a comes before b

strcmp(a, b) is the same, but with C-strings (which are NUL-terminated). The exact value returned by strcmp("cat", "dog") is implementation-dependent, but it will be negative.

Should this be 0 and 1 of the Uno/Nano? Will using these pins cause serial data errors?

Equal returns "0", not "1", and not-equal returns "-1"


char cat[] = {"dog"};
char dog[] = {"cat"};

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

  if (strcmp(cat, cat) == 0)
    Serial.println("Good!"); // returns this
  else
    Serial.println("Try again");

  if (strcmp(cat, dog) == 0)
    Serial.println("Good!");
  else
    Serial.println("Try again"); // returns this
}

void loop() {}

Another solution is use definitions (even easier than enums)

#define S 0
#define O 1
#define N 2
#define E 3

Then you could make a uint8_t array (byte array) with these.

A define will literally just copy the value of the define when you compile your code. So you can write

Int8_t myValue = S;
Int8_t myOtherValue = N;
If (myValue == myOtherValur)
{}
If (myValue == N)
{}

1 letter defines are never a good idea - you could go for constexpr of the byte but in my opinion an enum is more suited

enum : byte {UNKNOWN, SUD, OUEST, NORD, EST};

And if you need to mix them to get like south west then give them power of 2 values (1,2,4,8) and 0 for UNKNOW then you can use bitwise operations and masking.

1 Like

Single capital letters are reserved. You shouldn't use them for identifiers.

In C++, I know of only one capital letter that is somewhat reserved as part of the standard library (I for complex numbers).

https://en.cppreference.com/w/c/numeric/complex/I

Outside of this case, single capital letters are generally not reserved by the language itself, but you should avoid using single capital letters as names for variables or types a they are easy to get wrong, hard to search and replace for etc...

C++ reserved words include regular language keywords like int, for, while, or class, those defined in the standard libraries and identifiers starting with double underscores or an underscore followed by a capital letter are reserved for implementation use and should not be used in any namespace to avoid potential conflicts.

1 Like

They're reserved for the Arduino core is what I was told. F, and B are two examples.

ok - did not know that from Arduino but indeed F and Bnnn are examples

B[0-9]+ B[01]+ :

F:

Yes - I knew about F and Bnnn as I said.

I did not know Arduino reserved the one letter words for the Arduino core

I didn't know about the 1-letter reserved words but it seems like a poor idea.

B by itself doesn't seem to be defined, just B followed by a number of binary digits.

indeed B by itself is not

I may be wrong about it. I do remember hearing that a long time ago though. But I avoid single letters names for other reasons.

There's at least one more that messes things up but I don't remember what it is.

Either way, single letters make terrible names.

1 Like

I can see them doing that :slight_smile:

1 Like

Good point. Definetely add add a prefix. Something like D_UP

Its probably not the best programming practise for defines like this compared to an enum but for a small project its easy, and easy to do maths on if needs be.