1

I want to iterate the following 2d string array in C language; this is the code for iterating:

char list [][] ={{"dan","1"},{"sara","2"},{"loura","3"}};

for(i=0; i < 3;i++){

    for(j=0; j < 2;j++){

        if(strcmp(list[i][0],data)==0)
        {
            /*some code*/              
        }

    }//end column 


}// end row for

I got many warnings like "array type has incomplete element type". I think the problem is in the 2d array. I tried other ways of initializing like:

 char **list[][]=......

but that didn't work either.

5
  • 2
    Are you actually aware what char **list[][] would be? Don't just do trial and error. Commented Nov 28, 2015 at 13:55
  • What do you need? What exact messages do you get and where exactly? The definition should actually report an error, not just a warning. Are the strings supposed to change or are they constant? If non-constant: you you intend to change them in the array or just change the whole entries? Commented Nov 28, 2015 at 14:03
  • Ok see, this 2d array will not change, I am using it as database point of view, I need to access them and view them in certain condition. But I have never worked with 2d arrays in c that is why I am confused Commented Nov 28, 2015 at 14:06
  • BTW the strings written in my array are not the real ones, because they are too long. I want to access the array, compare the name, if it is found I want to print the number associated with it. Commented Nov 28, 2015 at 14:07
  • char **list[][], is not a pointer to a 2d array of char, instead it is 2d array of pointers which hold addresses of pointers of chars, you just can't initiate that way. Commented Nov 28, 2015 at 14:09

3 Answers 3

2

According to your comment the array will never change, you should make it constant. Also use pointers to the entries. The latter avoid the need to provide the max. size of characters per "string" and avoids waisting space:

const char * const list[][2] = { { "...", "..." } , ... };

This is a 2D array of pointers to char. The initialiser will set the pointers to the string literals given in the initialiser. This is the most comfortable (in the sense of automatic memory space sizing) you can get. The compiler can deduce the outer (leftmost!) dimension by the number of pairs in the initialiser. For the inner dimension, you have to specify. The sizes of the strings literals are not relevant for the array, as we use pointers (the data is not stored in the array itself).

The first const tells the compiler the object pointed to will not be modified. The second tells the same for the pointer itself (which implies the whole array will not be modified).

With this, you can use strcmp as you used in your question:

strcmp(list[i][0], data)

Make sure data is always properly terminated (i.e. '\0' at the end).

Update: According to your edit, you want to access the second entry as a number. Maybe an integer would then be better than a string. For this, you need a 1D array of a struct:

const struct {
    const char *name;
    int number;
} list[] = { { .name = "name", .number = 15 } , ... };

(The .name =/.number = parts are designated initialisers; standard since C99.)

Usage:

strcmp(list[i].name, data)
int my_number = list[i].number;

That way you may process the integer part easier and you name both entries easier. Even if you still use two strings, this might be the better approach, because you should use arrays only if all entries have the same semantics, otherwise a struct would be more appropriate.

Sign up to request clarification or add additional context in comments.

7 Comments

@AMH9: Welcome. Just think about the Updated variant. You likely will also notice it results in better readable/maintainable code;-)
What is const * const list[][] ?
@Alexguitar: I explained the consts in the text. Where is your exact problem?
pastebin.com/SmUJ1NWg because that's what I get when trying to compile a program with that line of code.
what I'm trying to say is it should probably be const char * const list[][]
|
1

if(strcmp(list[i][0],data)==0)

should be

if(strcmp(list[i],data)==0)

You want the address of the string, not the first element.

12 Comments

@ameyCU because I want to access the next element (list[i][1])if the condition is true
@AMH9 Yes , I know that's why you need a 3-d char array. And the previous comment was for the answer .
@ameyCU Yes it does: printf("%p\n", list[0]);
Using printf to verify an address is a very bad idea. This because it does not show the actual type of the pointer. Also note that printf("%p\n", list[0]) is undefined behaviour, because printf requires a void * for %p.
@Olaf, it's a great idea in this case because I simply wanted to show AMH9 that the syntax does resolve to an address. Also, the behavior is deterministic because an address is an address is an address regardless of what's stored there: the %p handles it just fine.
|
1

You should declare it like this

char list[][2][6] = {{"dan", "1"}, {"sara", "2"}, {"loura", "3"}};
  1. It's an array of arrays of arrays of chars. So a 3D char array. You only had 2 pairs of [].
  2. You must specify all but the first dimension. It wouldn't hurt to say char[3][2][6] either.
  3. The last size "6" is the size of the longest string "loura" plus the null-terminating char

6 Comments

If I do it this way, does the iteration method in my code still valid?
The C standard does not provide a type string. It is just convention how a sequence of char is interpreted as "string".
This list[i][0] will get only names e.g. "dan" then "sara". If that's what you want it's valid.
@Olaf yes I know, that is why I am using pointer to first char of chars sequence.
@Olaf interesting. Just searched through a draft version and the word "string" doesn't appear. Didn't know that
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.