views:

76

answers:

4

Hey everyone, I am getting a compile error in my code, and I cannot figure out what to do. Here's the block:

#include <stdio.h>
#include <string.h>    
/*
 * Function to return index at which team ID input is stored
 */
int getIndex(char* id, char* idList[][50]) {
    int k;
    for (k=0; k<50; k++) {
        if (strcmp(id,idList[k])==0) {
            return k;
        }
    }
    printf("Error in getIndex function.\n");
    return -1;
}

and the error says

Passing argument 2 of 'strcmp' from incompatible pointer type

The error occurs on the 8th line of code in the block (the if statement).

EDIT (posted here on behalf of Michael, since he can't edit his posts yet)

I'll specify what I wanted to do, since I didn't really do a good job at that.

I wanted id[] which is just supposed to be a array of up to 50 characters to be compared with idList[][] which is an array of Strings (up to 50 Strings up to 50 characters each).

I changed my code to this,

/*
 * Function to return index at which team ID input is stored
 */
int getIndex(char* id[], char* idList[][50]) {
    int k;
    for (k=0; k<50; k++) {
        if (strcmp(id[],idList[k][])==0) {
            return k;
        }
    }
    printf("Error in getIndex function.\n");
    return -1;
}

but got an error saying:

Expected expression ']' before token
+4  A: 

The expression idList[k] is a char* [50] object, not a char* object. You probably intended to make the signature char idList[][50] or char* idList[50], or you probably meant to give a second index (as in idList[k][j]). That is what the error message means. Obviously, you know the function best, so you are in the best position to know exactly which of these options you meant.

Edit
Based on this updated information, what you probably want is this:

int getIndex(const char* id, const char* id_list[], int id_list_length) {
    for (int i = 0; i < id_list_length; i++) {
        if (!strcmp(id, id_list[i])) {
            return i;
        }
    }
    printf("Error in getIndex function; ID \"%s\" not found.\n", id);
    return -1;
}

First, notice that I use const char* instead of char*. This is an improvement in that it tells the compiler that the contents of the string will not be modified. Secondly, the size of the list is given in the parameter rather than hard-coded into the function signature. Lastly, there are far fewer uses of brackets (i.e. []) in the signature (typically, in C and C++, it is generally more common to see pointers in the signature, especially given that arrays are effectively nothing more than pointers to repeated data). You can enforce the length requirement where you create the array, however, it is generally more common to allow the lengths to be dynamic and computed automatically. Here is an example use:

const char* id_list[] = { "Alpha", "Bravo", "Charlie" };
int id_list_length = 3;
int zero = getIndex("Alpha", id_list, id_list_length);
int one = getIndex("Bravo", id_list, id_list_length);
int two = getIndex("Charlie", id_list, id_list_length);
int negative_one = getIndex("Not in there", id_list, id_list_length);

You might also consider modifying this to use NULL as termination character for the list:

int getIndex(const char* id, const char* null_terminated_id_list[]) {
    for (int i = 0; null_terminated_id_list[i] != NULL; i++) {
        if (!strcmp(id, null_terminated_id_list[i])) {
            return i;
        }
    }
    printf("Error in getIndex function; ID \"%s\" not found.\n", id);
    return -1;
}

Then you don't even need to record the length of the list, you can write something like:

const char* id_list[] = { "Alpha", "Bravo", "Charlie", NULL };
int zero = getIndex("Alpha", id_list);
int one = getIndex("Bravo", id_list);
int two = getIndex("Charlie", id_list);
int negative_one = getIndex("Not in there", id_list);
Michael Aaron Safyan
I was trying to compare id[] (I left out the brackets in the code) with idList[k][] (I'm unsure if k is in the right bracket). I want to compare the 'string' id to all the 'strings' in idList (holds 50 strings of 50 characters each).
Michael
@Michael: if idList is a list of 50 strings, then it could be declared as `char *idList[50]`, bearing in mind that the compiler won't enforce that it really is 50. You've declared `idList` as a 2-d array of `char*`, but it seems you want an array of `char*`.
Steve Jessop
A: 

In VS, I get this error:

error C2664: 'strcmp' : cannot convert parameter 2 from 'char *[50]' to 'const char *'

The problem is that idList[k] is an array of pointers, not an array of characters.

In C, a string is either a char* or a char[], but not char*[]. A char*[] would be an array of strings, which means a char*[][] (which is what your function currently takes) is an array of arrays of strings...

You'll either need to change your function signature (to something like char idList[][50] or char* idList[50]), or somehow add a second index (something like idList[k][j]) for the signature to match correctly.

Do you have an array of strings, or an array of arrays of strings?

  • If you have an array of strings, fix the function signature: char* idList[50]
  • If you have an array of arrays of strings, you'll need to change the body of the function, and maybe the signature, to pass the size of each of those inner arrays:

Example code for the 2nd option...

int getIndex(char* id, char* idList[][50], size_t idListSizes[50]) {
  int k, l;
  for (k=0; k<50; k++) {
    for (l=0; l<idListSizes[k]; l++) {
      if (strcmp(id,idList[k][l])==0) {
        /* somehow return both k and l */

EDIT

After seeing your edit (which you posted as an answer to your question :)), this is what you want:

int getIndex(char id[50], char idList[50][50]) {
  int k;
  for (k=0; k<50; k++) {
    if (strcmp(id,idList[k])==0) {
      return k;
    }
  }
  printf("Error in getIndex function.\n");
  return -1;
}

The key here is that you don't have to use char* to represent a string. A char[] is the same thing.

And also note that C won't enforce the size in some cases. With the code I just posted, this will still compile:

char blah[70];
char blee[14][50];
return getIndex(blah, blee);

Though this won't:

char blah[70];
char blee[14][27];
return getIndex(blah, blee);

EDIT

One last thing, you need your strings to be size 51, because of the terminating null. For example:

char test[] = "test"; /* This is actually an array of size 5, not 4 */
char alt[] = { 't', 'e', 's', 't', '\0' }; /* same content as test... */
Merlyn Morgan-Graham
A: 

This is an update, since it's not letting me reply/comment your posts, also I changed the code a bit.

First I'll specify what I wanted to do, since I didn't really do a good job at that.

I wanted id[] which is just supposed to be a array of up to 50 characters to be compared with idList[][] which is an array of Strings (up to 50 Strings up to 50 characters each).

I changed my code to this,

/*
 * Function to return index at which team ID input is stored
 */
int getIndex(char* id[], char* idList[][50]) {
    int k;
    for (k=0; k<50; k++) {
        if (strcmp(id[],idList[k][])==0) {
            return k;
        }
    }
    printf("Error in getIndex function.\n");
    return -1;
}

but got an error saying:

Expected expression ']' before token
Michael
You should just edit your question. Put * * EDIT * * (without the spaces between the asterisks/word - to make **EDIT** bold) at the bottom, and just paste what you wrote here after that.
Merlyn Morgan-Graham
OK, thanks, I'll do that now.
Michael
Actually, I think that it won't let me since I'm not a registered user and I refreshed the page.
Michael
@Michael: Done. You can delete this now if you like :)
Merlyn Morgan-Graham
A: 

If your idList parameter is supposed to represent a linear array of IDs, then it should be declared as either char idList[][50] or char *idList[], depending on whether the array itself actually provides the string memory (the former) or the string memory is allocated elsewhere (the latter). Most likely you need the former variant.

What you have now - char *idList[][50] looks like a weird hybrid of the two and makes no sense within the context of your intent, the way I understand it.

AndreyT