dorothy
dorothy

Reputation: 1243

C iterate array of struct

say I have declare a struct

struct mystruct {
  char a[10];
  double b;
} 

struct mystruct array[20] = { 
   {'test1',1.0},
   {'test2',2.0}  <---- I just want to declare 2 items first because I am going to add new ones later.
};
int i;
for( i=0; array[i].a != NULL ;i++){ 
    ....  <--- so here I just want to display what is initialized first
} 

However, the for loop display past the 2 items ( ie to 20 items but all the rest are garbage ). I just want to display currently only what is initialized, even though i declared to store 20 of them. How to do it? thanks.

I am using C90 standard. Also, let's say I added more items in future , but still lesser than 20 items, i would just want to display until the "last item that is valid" .

Upvotes: 2

Views: 4245

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 753930

For compilers that will accept the initializer syntax (that should be any standard C compiler), you should be able to write:

struct mystruct
{
  char a[10];
  double b;
};  // semi-colon added!

struct mystruct array[20] =
{ 
   { "test1", 1.0 },  // character strings!
   { "test2", 2.0 },
};
enum { ARRAY_SIZE = sizeof(array) / sizeof(array[0]) };

int i;
for (i = 0; i < ARRAY_SIZE && array[i].a[0] != '\0'; i++)
{ 
    printf("[%s] => %f\n", array[i].a, array[i].b);
}

Upvotes: 6

Petr Skocik
Petr Skocik

Reputation: 60068

If you have only initialized three items, you usually have to remember that piece of information and do

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

In case you actively zeroed the rest of the array (in a for loop or by memset for example) or if you declared it as global variable (which are guaranteed to be zeroed by the compiler), you can do something similar to what you were trying to do:

for( i=0; array[i].a != '\0' ;i++){ ... }

Since array[i].a is a char, you should compare it to chars. Coincidentally, thanks to some implicit conversions (char to int), you should also be able to compare it to ints so

 for( i=0; array[i].a != 0 ;i++){ ... } 

should be OK as well. Transitively, you're NULL version should work too, since NULL is just a macro for 0 (on most computer architectures anyway), but you shouldn't be using that because the (human) convention is that it should only be used for empty pointers.

Upvotes: 1

Related Questions