0

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);
}
0

3 Answers 3

3

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.

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

3 Comments

Thank you, this did it for me. But I wonder why I get the error, 'Implicitly declaring library function 'strcpy' with type 'char*(char*, const char *)''
you should #include <string.h>
"You have to specify the length of the char array" is incorrect. "As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member." C11dr §6.7.2.1 18.
1

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.

13 Comments

These seems like a very lengthy route, no?
@MichaelRader Perhaps, but it's the dynamic way of doing it, and eventually you will have to learn how to deal with it, you must learn.
strdup will do the length, malloc and copy for you pubs.opengroup.org/onlinepubs/009695399/functions/strdup.html
strdup is a posix standard
@MichaelRader I understand, but keep in mind that you should read about this things.
|
0
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);
}

6 Comments

@HAL9000 flexible array members like Person.name are an addition of C99 intended to be used like in this answer, although in a real implementation it would be necessary to add another field with the size of name. See: en.wikipedia.org/wiki/Flexible_array_member
@Fernando, thank you I'm learning it but I'll never use it in all my life :-)
@HAL9000 it has a typo in sizeof(person), it needs to include some headers like string.h and stdlib.h, and calculateBMI() isn't defined. Fixing those it compiles with gcc -std=c99 -o test test.c. PD: I don't think I ever used this feature :)
This really is an up-to-date way of doing things. (note sizeof(person) to sizeof(Person))
@Fernando Do not agree with "necessary to add another field with the size of name". Such a field may help with some other functionality, but is not necessary.
|

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.