String array lookiup using strcmp

I am pretty new to C programming. I am trying to program a lookup function to match a RFID tag to a table of valid tag numbers (a multi-dimensional array).

My displays would indicate that a typed-in code should match an entry in the array, the program does not display “Matched” within the strcmp for/next loop. (see output results below)

Any help would be appreciated…

------------CODE----------------------------

char *tags =
{ “0F03028D09”,
“22007A80C6”,
“0415ED2CCA”,
“2100E0C393”,
“36008DB168”
};

int i;

int val = 0;
char code[10];
int bytesread = 0;

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

void loop()
{
Serial.println(“Enter 10 character tag”);
bytesread = 0;
while(bytesread<10) { // read 10 digit code
if( Serial.available() > 0) {
val = Serial.read();
if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}
}

Serial.println(code);

// for (int i = 0; i < 5; i++)
for (i = 0; i < 5; i++)
{
Serial.print(tags*);*

  • Serial.print(" - ");*
  • Serial.println(code);*
    _ if (strcmp(tags*, code) == 0) {_
    _
    Serial.println(“Matched”);_
    _
    break;_
    _
    } _
    _
    }_
    _
    delay( 500 );_
    _
    }*_

----------------output------------
Enter 10 character tag
36008DB168
0F03028D09 - 36008DB168
22007A80C6 - 36008DB168
0415ED2CCA - 36008DB168
2100E0C393 - 36008DB168
36008DB168 - 36008DB168

You're not terminating the input string with a '\0' (zero).

char code[11]; 
..
..
..

if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading 
          code[bytesread++] = '\0';         // terminate the string.
           break;                               // stop reading 
         } 
         code[bytesread] = val;         // add the digit           
         bytesread++;                   // ready

or you could use strncmp.

Fantastic!!

I assume that strcmp needs the terminating null to know when to stop comparing bytes.

Thanks for your help AWOL!

I assume that strcmp needs the terminating null to know when to stop comparing bytes

Correct.

The strings you defined in "tags" are automatically terminated by the compiler.

It's just how 'C' represents strings.

AWOL, Is there a way to determine the number of bytes in the table. When I use sizeof(tags) I get 10 - the length of the first entry (not sure why I don't get 11 since sizeof(code) returns 11)

I need to do some serious study on C language...

When I use sizeof(tags) I get 10 - the length of the first entry

Actually, I think the number 10 is returned because your array has 5 char*s. And each of them is two bytes.

2 * 5 = 10;

sizeof(tags) gives you 10 because that’s the length of the tags array,
in bytes. Each array element is a pointer to a char, thus two bytes.
You have 5 elements in the array so… 5*2 => 10.

Your RFID codes are “technically” not part of the array, they’re just
chunks of initialized memory pointed to by an array element of tags.

If you want to count how many bytes are in all of your codes, you’d
have to do something like this:

    int sum = 0;
    for (int i=0; i<sizeof(tags)/sizeof(tags[1]); i++) {
        sum += strlen(tags[i]);
    }

Alas, this won’t count the NULs at the end of each string.

The expression
sizeof(tags)/sizeof(tags[1])
give you the number of elements in your tags array.

Hope that helps.

-Rusty-

Thanks! Makes more sense now.

Of course sizeof(tags)/sizeof(tags[1]) only works because all entries are the same length.

  • Ron
sizeof(tags)/sizeof(tags[1])

Best to use

sizeof(tags)/sizeof(tags[0])

Of course sizeof(tags)/sizeof(tags[1]) only works because all entries are the same length.

tags is an array of pointers. tags[1] is a pointer. The expression doesn't depend at all on the data that the pointers point to. If you were to change the lengths of the strings, it would still yield the same result.

Mikal

The expression doesn’t depend at all on the data that the pointers point to. If you were to change the lengths of the strings, it would still yield the same result.

I think AWOL was concidering the possibility that the tags end up being just a single string, thus tags[1] will be ‘wrong’.
But I think that any index will yield the same result, although it is not ‘good practice’.

[edit]I assumed you where replying to AWOL, but you where not.
/me miss quote.[/edit]

But I think that any index will yield the same result, although it is not 'good practice'.

Yeah, that's right. Funny, isn't it? You can use sizeof(tags[0xF3333]) and that will work just as well. The array element is never dereferenced in a sizeof expression.

And did you know that wherever you use the expression tags[0], you can also write it as 0[tags]? That's not the best practice either. :)

Mikal

I obviously have a learning curve with C.

I've been a programmer since 1973 but haven't used C very much.

Since 1994 I was developing applications using Visual Basic, HTML, javacript, SQL, etc.

Programming microcontrollers is more fun for sure!

Originally, I was going to use sizeof(tags)/sizeof(char *) but thought that might blow away a noob or two. :-) Actually, that sorta thing might be better if the array elements were a user-defined type, as defined with #typedef.

Why I used [1] instead of [0]? Got me. Musta been those mental blocks my folks gave me for Christmas one year. :-)

sizeof(tags)/sizeof(char *)

But that's not very useful, whereas

define SIZEOF(x) (sizeof ((x)) / sizeof ((x)[0]))

is pretty universal.

I think

const byte ARRAY_SIZE = 10;

Is even more helpful / 'good practice'.

The macro solution will bite you in the ass someday. :)

That's always assuming you know the size in advance!

That's always assuming you know the size in advance!

And I strongly advice everyone to know the size, or require information about it.