1

In my project, I am asked to store my 2D array of words in a dynamic data structure, then use them in other functions for other purposes, but I am confused how should I do this. I do understand, how to name them separately like:

#include <stdio.h>
#include <stdlib.h>

typedef struct Names {
    char *name[5];
} Names;

void func(Names y) {
    printf("%s\n%s", y.name[0], y.name[1]);
}

int main()
{
    Names y;
    y.name[0] = "John";
    y.name[1] = "Luke";
    func(y);

    return 0;
}

But what if I wanted to do this as a 2d array. So normally I would do char names[][10] = {"John", "Luke", etc..}; but how do I store that in a struct? I mean if I did

#include <stdio.h>
#include <stdlib.h>

typedef struct Names {
    char *name[5][10];
} Names;

void func(Names y) {
    printf("%s\n%s", y.name[0], y.name[1]);
}

int main()
{
    Names y;
    y.name[][10] = {"John", "Luke"};
    func(y);

    return 0;
}

That would just give errors and make no sense.

1

2 Answers 2

2

This is the official way to do it (see Nested initialization in: Struct and union initialization):

#include <stdio.h>

typedef struct Names {
    const char *name[2][2];
} Names;

void func(Names* y) {
    printf("%s, %s\n", y->name[0][0], y->name[0][1]);
    printf("%s, %s\n", y->name[1][0], y->name[1][1]);
}

int main()
{
    Names y = { .name={{"John", "Luke"}, {"Jack", "Jim"}}};
    func(&y);

    return 0;
}

Also the following works for backwords-compatibility reasons:

#include <stdio.h>

typedef struct Names {
    const char *name[2][2];
} Names;

void func(Names* y) {
    printf("%s, %s\n", y->name[0][0], y->name[0][1]);
    printf("%s, %s\n", y->name[1][0], y->name[1][1]);
}

int main()
{
    Names y = {"John", "Luke", "Jack", "Jim"};
    func(&y);

    return 0;
}

The above is managing string constants stored in const char pointers, for variable strings of up to 9 chars lentgh with a trailing zero-terminator, something like the following will be possible (I made compile-time constants for 5 and 9):

#include <stdio.h>

enum {
    NAME_COUNT = 5,
    NAME_LENGTH = 9
};
typedef struct Names {
    char name[NAME_COUNT][NAME_LENGTH+1];
} Names;

void func(Names* y) {
    for (int i=0; i<NAME_COUNT; ++i) {
        printf("%s\n", y->name[i]);
    }
}

int main()
{
    Names y = { .name={"John", "Olivia", "Luke", "Mary", "Jane" }};
    func(&y);

    return 0;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you a lot :)
And what if I have another function void func2(something);. In my void func(Names *y); I would like to call that func2 function like this func2(y->name[0][0]); Just pass that name to another function, what should that func2(something); accept instead of that something ?
@Norbertas You mean how to access the address of one of the embedded strings members of the struct?
Yes, for instance (talking about the first code sample of yours) I want to pass "John" in func to func2, how should the func2 be declared? Like func2(char name[0][5]) ? So it contains one word of 5 characters?
@Norbertas Accessing the ith name within the structure is done by &y->name[i].
1

I think what you may be missing is the fact that char *name[5]; is not really a 2d array of words, it's an array of 5 pointers to char, you then make the two first pointers of that array point to two string literals. In the second expression you have a 5 by 10 2d array of pointers to char, each one of these pointer can also point to its own string literal, so naturally the expression:

y.name[][10] = {"John", "Luke"};

Is not correct for several reasons, the compiler needs to know both dimensions of the array to know to which pointer you want to assign the string literal, knowing this you'll note that the assigned expression makes little sense.

Example:

y.name[1][1] = "John"; 

Here you would assign the string literal "John" to the pointer located in the index [1][1] of the array of pointers.

Now, if you want an array of 5 words each one containing 10 characters, including the null byte you would simply use:

char name [5][10]

Note that in this configuration you can't simply assign the strings, you'll need to copy them using somenthing like strcpy.

strcpy(y.name[0], "John");

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.