-4

i create a structure in c like this

struct book {  
   char name;  
   int page;  
} b2,b3,b4;  

how can i print these using a for loop.
i mean

for(int i=2 ; i<5 ; ++i)  
    printf("%c %d", b{i}.name , b{i}.page); //bi.name will not work obviously

is there some kind of special operation that need to do this ?
and i sincerely apologize if it has been answered somewhere else on the site already. i don't know myself what i'm supposed to search for precisely.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Shashi
  • 746
  • 10
  • 39
  • 1
    I did a Google search with `dynamic variable names in c`, which returned several relevant links. – AntonH Jun 03 '14 at 23:40
  • 6
    Why not declare an array of structs? – haccks Jun 03 '14 at 23:40
  • 1
    Use an array of `struct book`. – Michael Burr Jun 03 '14 at 23:40
  • `b{i}.page` you're sure not to have a typo here?? Meant `b[i].page` actually? – πάντα ῥεῖ Jun 03 '14 at 23:54
  • nah .. i actually meant to create structure variable names at run time using for loop. apparently can't do it in c. – Shashi Jun 03 '14 at 23:57
  • @BrainDead Variable names are fixed at compile time, thus you can't generate them using changing variables and set them up at runtime, c++ doesn't have any reflection mechanisms to serve such. The closest thing you can get is using a standard container to store your structure instances and use `i` as an index for accessing. – πάντα ῥεῖ Jun 04 '14 at 00:17
  • @πάνταῥεῖ why did you remove the C tag and leave C++, for a C question? – Cheers and hth. - Alf Jun 04 '14 at 00:23
  • Remember that `char` type specifies a single character, *not a string of characters*. Also the `int` type allows negative numbers, and I have yet to see a book with negative pages. – Thomas Matthews Jun 04 '14 at 01:04
  • Variables (instances) of structures can be created at run-time, see *dynamic memory allocation*, which is different between C and C++. Another reason they are different languages. So which language are you programming in? – Thomas Matthews Jun 04 '14 at 01:06

3 Answers3

4

I have a solution :

Store structure into an Array of pointer and loop through it

struct book **arr = malloc(sizeof(struct book *) * 4);

arr[0] = &b2;
arr[1] = &b3;
arr[2] = &b4;
arr[3] = NULL;

for (int i=0; i < 3; ++i)
{
   printf("%c %d", arr[i]->name , arr[i]->page);
}

EDIT:

Or like other community gyus said, create at begining an array of structure (easier to manipulate)

Example :

struct book books[3];

Or

struct book *books = malloc(sizeof(struct book) * 3);
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
1

You could use arrays and macros:

struct book {  
   char name;  
   int page;  
};  

#ifndef __cplusplus
struct
#endif
book library[3];

#define b2 (library[0])
#define b3 (library[1])
#define b4 (library[2])

void initialize(void)
{
    b2.name = 'a';
    b2.page = 5;
    b3.name = 'F';
    b3.page = -85;
    b4.name = '$';
    b4.page = 65535;
}


void Print_Library(void)
{
  unsigned int i = 0;
  for (i = 0; i < 3; ++i)
  {
     printf("First character of book %d: %c\n", i, library[i].name);
     printf("Page of book %d: %d\n", i, library.page);
     printf("\n");
  }
}

The name field is a single character not a string.

Note: I used the #if preprocessor directive because instances of structures are defined differently between C and C++ and you specified both.

Edit 1: Accessing variables by name during run-time.
Although I have never needed to access variables by name during run-time, one method is to map variables to their names.

struct book; // forward declaration, see above.

struct Variable_Name_Entry
{
#ifdef __cplusplus  // Required since you tagged both languages
  std::string  name;
  book *       p_variable;
#else
  char         name[16];
  struct book * p_variable;
#endif
};

#ifndef __cplusplus
struct
#endif
Variable_Name_Entry  variable_names[] =
{
  {"b2", &b2},
  {"b3", &b3},
  {"b4", &b4},
};
const unsigned int number_of_variable_names =
  sizeof(variable_names) / sizeof(variable_names[0]);

#ifndef __cplusplus
struct
#endif
book * name_to_variable(const char * p_name)
{
  unsigned int i = 0;
  for (i = 0; i < number_of_variable_names; ++i)
  {
#ifdef __cplusplus
    if (variable_names[i].name == p_name)
#else
    if (strcmp(variable_names[i].name, p_name) == 0)
#endif
    {
      return variable_names[i].p_variable;
    }
  }
  return NULL;
}

Do you really need to access variable by names or is there a different design available?

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

You can collect pointers to the variables in an array, e.g. like this in C++11:

for( auto p : {&b2, &b3, &b4} )
{
    cout << p->name << " " << p->page << endl;
}

I leave it to you to create similar C language solution, if you want that (the question was/is tagged both C++ and C).

In C the array has to be created more manually, so to speak.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331