[SOLVED]Comparing whole arrays?

Hi there!

I have two arrays:

int disarmCode[4] = {1,2,3,4};
int tempArray[4] = {1,2,3,4};

Is it possible to compare the arrays in a way that I can, basically, ask the Arduino, "Are these arrays EXACTLY the same?"

Maybe like this?

if(tempArray == disarmCode) {
            //do something
          }

Thanks!

how about like this:

for (int i = 0;  i < 4; i++)
{
  if( tempArray[i] != disarmCode[i] ) 
  {
    Serial.println("not equal");
    //set your boolean flag here
    break;
  }
}

Another way is to use memcmp(). First, test to see if the sizes are the same:

int disarmCode[4] = {1,2,3,4};
int tempArray[4] = {1,2,3,4};

int oneElementSize = sizeof(disarmCode[0]);

if (sizeof(tempArray[0] == oneElementSize) {        // Are the sizes of the elements the same?
   if (sizeof(tempArray) == sizeof(disarmCode)) {   // Are the number of elements the same?
      if (memcmp(tempArray, disarmCode, sizeof(tempArray) * oneElementSize) == 0)
        Serial.println("They match");
      }
   }
}

I haven't tested this code, but I think it would work.

Is it possible to compare the arrays in a way that I can, basically, ask the Arduino, "Are these arrays EXACTLY the same?"

Not without comparing each element individually, no.

econjack: Another way is to use memcmp(). First, test to see if the sizes are the same:

int disarmCode[4] = {1,2,3,4};
int tempArray[4] = {1,2,3,4};

int oneElementSize = sizeof(disarmCode[0]);

if (sizeof(tempArray[0] == oneElementSize) {        // Are the sizes of the elements the same?    if (sizeof(tempArray) == sizeof(disarmCode)) {   // Are the number of elements the same?       if (memcmp(tempArray, disarmCode, sizeof(tempArray) * oneElementSize) == 0)         Serial.println("They match");       }    } }




I haven't tested this code, but I think it would work.

That only compares their SIZE not cells. I want to see if one array is a copy of another array.

How do you know the length of the arrays? Is it fixed at 4 items like your example?

-jim lee

jimLee: How do you know the length of the arrays? Is it fixed at 4 items like your example?

-jim lee

Yes. They will always be 4 cells. A user is entering a 4-digit code and this code checks to see (after he enters in 4 digits on a keypad), if he entered in the correct code.

I’d go with reply #1 then, with 1 change:

for (int byte i = 0; i < 4; i++)
{

That only compares their SIZE not cells. I want to see if one array is a copy of another array.

not so, read the memcmp manual

the memcmp compares the 2 chuncks of memory with the size of the array
The check if they are the same size speed up things and makes sure that you do not
compare wrongly because variables lie against each other in the memory

(not tested example, but to get the idea)

int disarmCode[4] = {1,2,3,4};
int tempArray[3] = {1,2,3};
int x = 4;

for (int i = 0;  i < 4; i++)
{
  if( tempArray[i] != disarmCode[i] ) 
  {
    Serial.println("not equal");
    //set your boolean flag here
    break;
  }
}

Another way is to calculate a checksum of both arrays and compare the values.
If the checksum is not equal the arrays are not equal.
If the checksum is equal there is a great chance the arrays are equal.

a simple checksum could be the sum. When the temp code is entered the sum can be calculated between keypresses. The sum of the disarm code is only calculated once.
Better checksums include CRC16 and CRC32 but these costs more to calculate than comparing the arrays.

finally instead of an array of 4 digits why not use an unsigned long?
can hold a 9 digit number which can be easily compared.

robtillaart:

That only compares their SIZE not cells. I want to see if one array is a copy of another array.

not so, read the memcmp manual

the memcmp compares the 2 chuncks of memory with the size of the array
The check if they are the same size speed up things and makes sure that you do not
compare wrongly because variables lie against each other in the memory

(not tested example, but to get the idea)

int disarmCode[4] = {1,2,3,4};

int tempArray[3] = {1,2,3};
int x = 4;

for (int i = 0;  i < 4; i++)
{
 if( tempArray[i] != disarmCode[i] )
 {
   Serial.println(“not equal”);
   //set your boolean flag here
   break;
 }
}




Another way is to calculate a checksum of both arrays and compare the values. 
If the checksum is not equal the arrays are not equal.
If the checksum is equal there is a great chance the arrays are equal.

a simple checksum could be the sum. When the temp code is entered the sum can be calculated between keypresses. The sum of the disarm code is only calculated once.
Better checksums include CRC16 and CRC32 but these costs more to calculate than comparing the arrays.

finally instead of an array of 4 digits why not use an unsigned long?
can hold a 9 digit number which can be easily compared.

Sorry. My reply came out wrong.

For the mcmcmp method, would something like this work?

if((memcmp(tempArray, disarmCode, 4) * 4) == 0) {
           //Right
            Serial.println("CORRECT!");
            currentState = 3;
            minutes = 0;
            seconds = 0;
            clearDisplay();
          } else {
            //wrong
            Serial.println("WRONG!");
            timerDelay = 500;
            tempArrayIndex = 0;
          }

(I already know the size of the cells, so I entered in a 4 for the last argument).

Or just 1 compare with password an unsigned long: if (password == (temp[3] * 1000) + (temp[2]) * 100) + (temp[1]) * 10) + temp[0]){ // unlock }

Try this

int disarmCode[4] = {1,2,3,4};
int tempArray[4] = {1,2,3,4};
int tempArray2[4] = {1,5,3,4};

void setup() {
  Serial.begin(9600);
}

boolean checkArrays(int arrayA[],int arrayB[], long numItems) {

    boolean same = true;
    long i = 0;
    while(i<numItems && same) { 
      same = arrayA[i] == arrayB[i];
      i++;
    }
    return same;
  }
  
void loop() {

  delay(15000);
  Serial.print("disarmCode & tempArray "); Serial.println(checkArrays(disarmCode,tempArray,4));
  Serial.print("disarmCode & tempArray2 "); Serial.println(checkArrays(disarmCode,tempArray2,4));

}

Hope it helps.

-jim lee

That only compares their SIZE not cells. I want to see if one array is a copy of another array.

As robtillaart points out, it does a memory compare and can only come back with 0 on a perfect match. As for the other alternatives that have been offered, they essentially do the same thing, only they control the loop that walks through the elements. When I had my compiler company, all of the mem*() functions were hand-tweaked assembler and I doubt that a compiler would improve on them either in terms of code size or speed (although they were optimized for speed). As a general rule, it makes no sense to reinvent the wheel so memcmp() should do the trick. While some others rely on your fixed array sizes, my code doesn't make that assumption and that's often not a bad idea in the long run. Coding for fixed sizes has a way of coming back to haunt you later on.

@jimlee: Why make numItems and i a long when the native size is 16 bits?

Old habits die hard. I was in a hurry, The complier takes care of it and I write for different platforms.

-jim lee

jojoguy10: Yes. They will always be 4 cells. A user is entering a 4-digit code and this code checks to see (after he enters in 4 digits on a keypad), if he entered in the correct code.

If the array lengths are known and equal, one call to memcmp() will do the job. If you are storing the passwords as null-terminated ascii strings (which would be a reasonable approach IMO) then you could also compare then using strcmp(). If the keypad is only used to enter decimal digits then you also have the option of converting the four digit keypad input sequence to a single integer number which you could then compare directly with ==.

jimLee:
Try this

int disarmCode[4] = {1,2,3,4};

int tempArray[4] = {1,2,3,4};
int tempArray2[4] = {1,5,3,4};

void setup() {
  Serial.begin(9600);
}

boolean checkArrays(int arrayA,int arrayB, long numItems) {

boolean same = true;
    long i = 0;
    while(i<numItems && same) {
      same = arrayA[i] == arrayB[i];
      i++;
    }
    return same;
  }
 
void loop() {

delay(15000);
  Serial.print("disarmCode & tempArray "); Serial.println(checkArrays(disarmCode,tempArray,4));
  Serial.print("disarmCode & tempArray2 "); Serial.println(checkArrays(disarmCode,tempArray2,4));

}




Hope it helps.

-jim lee

Thanks so much Jim!

This worked perfectly! I’m considering this thread “SOLVED”!

Thanks everyone for your replies!