Michael Rader
Michael Rader

Reputation: 5967

How to use strings with structs in C?

I have seen the answer to this question but it is terribly uninformative for newbie's like myself and still can't manage to get it to work. I am trying to declare a member of the struct called "name" that takes a string value and then trying to figure out how to get that value and print it. Every way I have tried produces an error...

typedef struct {
    float height;
    int weight;
    char name[];
} Person;


void calculateBMI(Person x) {
    //printf will go here here
}


int main(int argc, const char * argv[]) {

    Person Michael;
    Michael.height = 62.0;
    Michael.weight = 168;
    Michael.name[] "Michael";

    Person Steve;
    Steve.height = 50.4;
    Steve.weight = 190;
    Steve.name = "Steven";

    calculateBMI(Michael);
    calculateBMI(Steve);
}

Upvotes: 0

Views: 188

Answers (3)

Jasen
Jasen

Reputation: 12442

typedef struct {
    float height;
    int weight;
    char name[];
} Person;

this struct has no size declared for the name this means that when you create the struct you must also create space for the name .

int main(int argc, const char * argv[])
{
    Person *Michael=malloc(sizeof(Person)+strlen("Michael")+1);
    if(!Michael)return 1;
    Michael->height = 62.0;
    Michael->weight = 168;
    strcpy(Michael->name,"Michael");

    calculateBMI(Michael);
    free(Michael);
}

Upvotes: 0

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53036

You can to declare the name member as char * and allocate space to copy the string into it

typedef struct {
    float height;
    int weight;
    char *name;
} Person;


size_t length;
const char *name = "Michael";


length       = strlen(name);
Michael.name = malloc(1 + length);

if (Michael.name != NULL)
    strcpy(Michael.name, name);

and then when you are done using the struct, don't forget to free

free(Michael.name);

or do as HAL9000 suggests, but this solution wont work for longer strings.

You could simplify this process by creating a helper function like

char *dupstr(const char *src)
{
    char   *dst;
    size_t  length;

    if (src == NULL)
        return NULL;
    length = strlen(src);
    dst    = malloc(1 + length);
    if (dst == NULL)
        return NULL;
    strcpy(dst, src);
    return dst;
}    

and then

typedef struct {
    float height;
    int weight;
    char *name;
} Person;

Michael.name = dupstr("Michael");

but you will also need to call free after finished using the struct.

Upvotes: 1

HAL9000
HAL9000

Reputation: 3761

You have to specify the length of the char array, like this:

typedef struct {
    float height;
    int weight;
    char name[30];
} Person;

Then you use strcpy to populate it:

int main(int argc, const char * argv[]) {

    Person Michael;
    Michael.height = 62.0;
    Michael.weight = 168;
    strcpy(Michael.name, "Michael");

    Person Steve;
    Steve.height = 50.4;
    Steve.weight = 190;
    strcpy(Steve.name, "Steven");

    calculateBMI(Michael);
    calculateBMI(Steve);
}

This solution will be the cleanest in all the common cases as you are allocating the space into the stack when you declare a new variable of type Person . In most complex scenarios you don't know the size of the char array and maybe you need to keep it as small as possible. In those case you can use a malloc solution.
Remember that everytime you are using malloc youy have to remember to free the allocated space when you are done with the data.

Upvotes: 3

Related Questions