简体   繁体   中英

C Structs and arrays

I can't get the code below to compile (see errors). Advice on correction would be appreciated.

#include <stdio.h>

typedef struct {
  char    *fldName;
  unsigned fldLen;
} Field;

typedef struct {
  char    *fldPrompt;
  unsigned startRow;
  unsigned startCol;
} Prompt;

typedef struct {
  Field   *fields[];
  Prompt  *prompts[];
  unsigned numFlds;  <<< invalid field declaration after empty field 
} Form;                    <<< in '(incomplete) struct (no name)'.

Field  firstName = { "fName", 12 };
Field  surName   = { "sName", 25 };
Field  gender    = { "gder", 1 };

Prompt fn        = { "First Name : ", 4, 10 };
Prompt sn        = { "Surname    : ", 6, 10 };
Prompt gn        = { "Gender     : ", 8, 10 };

int main (void)
{
  Form aForm = { { &firstName, &surName, &gender },
                 { &fn, &sn, &gn}, 
                 3 };  <<<  Multiple initializers for the same element
  return 0;             <<<  Too many initializers
}

All your errors stem from the fact that you incorrectly declare arrays inside your struct. You have to specify the size of the array; you cannot just use empty brackets. Ie this would work:

typedef struct {
    Field *fields[3];
    Prompt *prompts[3];
    unsigned numFlds;
} Form;

If you need to allow for varying number of elements, you'll have to use something else. For example, you can have both fields be pointers:

Field **fields;
Prompt **prompts;

But then you'll have to dynamically allocate and free memory for them, and you definitely won't be able to use aggregate initializer to initialize the struct.

You have declared arrays in the struct definition without specifying the bounds. This is not possible:

typedef struct {
    Field   *fields[];
    Prompt  *prompts[];
    unsigned numFlds; 
} Form;

You should either specify a number in the brackets or change it to a pointer type instead: Field **fields; . Always note that size of a structure is static and is known at compile time, thus, it can't have variable sized array inside itself. However, it can point to a variable sized array (as pointers have a constant size).

A structure normally can't hold a member with incomplete type (eg arrays without dimensions) because the compiler can't know that member's size, ie the offset of following members within the structure would be indeterminate. An exception to this rule is the last member, which may have incomplete array type (a so-called flexible array member ).

The solution: use fixed-sized arrays or pointers.

The following code [ just modified and introduced the size of the array ] and it compiled fine.

#include <stdio.h>

typedef struct {
  char    *fldName;
  unsigned fldLen;
} Field;

typedef struct {
  char    *fldPrompt;
  unsigned startRow;
  unsigned startCol;
} Prompt;

typedef struct {
  Field   *fields[3];
  Prompt  *prompts[3];
  unsigned numFlds;  // invalid field declaration after empty field 
} Form;                    // in '(incomplete) struct (no name)'.

Field  firstName = { "fName", 12 };
Field  surName   = { "sName", 25 };
Field  gender    = { "gder", 1 };

Prompt fn        = { "First Name : ", 4, 10 };
Prompt sn        = { "Surname    : ", 6, 10 };
Prompt gn        = { "Gender     : ", 8, 10 };

int main (void)
{
  Form aForm = { { &firstName, &surName, &gender },
                 { &fn, &sn, &gn}, 
                 3 };   // Multiple initializers for the same element
  return 0;             //  Too many initializers
}

Also, if you want more than 3 in Line 15, then you need to declare it double pointer and allocate memory and use it. But ensure to deallocate/free it, when not going to use it. Otherwise, it will result in memory leak.

The problem is that you can't initialize a zero lenght array.

if you chague the For declaration to:

typedef struct {
    Field   *fields[100];    
    Prompt  *prompts[100];    
    unsigned numFlds;  // <<< invalid field declaration after empty field
} Form;                    // <<< in '(incomplete) struct (no name)'.

It will work.

It looks like a linked list structure might be most appropriate to your needs.

By the way - are the Prompts and Fields always mapped one-to-one? If so, you could just store them in the same structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM