6

I am going to store string arrays in an array in C.

For example

{
{"hello", "world"},
{"my", "name", "is"},
{"i'm", "beginner", "point", "makes"}
}

I'd like to store above data.

I tried to use

char *arr1 = {"hello", "world"};
char *arr2 = {"my", "name", "is"};
char *arr3 = {"i'm", "beginner", "point", "makes"}

But I don't know how to store those arrays in one array.

Thanks in advance.

ps.

How to print all element with?

const char **arr[] = {arr1, arr2, arr3};
0

2 Answers 2

10

If you want a char** array, just do :

const char *arr1[] = {"hello", "world", NULL};
const char *arr2[] = {"my", "name", "is", NULL};
const char *arr3[] = {"i'm", "beginner", "point", "makes", NULL};

const char **arr[] = {arr1, arr2, arr3, NULL};

Note that the NULL terminators are here to keep track of the different arrays' sizes, just like in a NULL-terminated string.

int i, j;
for(i = 0; arr[i] != NULL; ++i) {
    for(j = 0; arr[i][j] != NULL; ++j) {
        printf("%s ", arr[i][j]);
    }
    printf("\n");
}

Which would outputs :

hello world
my name is
i'm beginner point makes
Sign up to request clarification or add additional context in comments.

13 Comments

Thanks for your answer. But could you help me how to pull from arr[]? arr[0] returns only first element of arr1[].
How do you tell how many strings are in each of arr[0], arr[1], arr[2]? One simple semi-conventional way would be to have a null pointer at the end of each sub-array: char *arr1[] = { "hello", "world", 0 };
@JonathanLeffler indeed the NULL terminated array seems to be simpler than keeping array sizes.
@user2433045 What do you mean by the array of arr[] ? arr is an array of char**, arr[0], arr[1] and arr[2] are arrays of char*, arr[i][j] are actual strings (char*). Since arr[0] is an array of char*, you would have to do char** temp = arr[0].
FYI, using C99 compound literals, you can initialize arr in one go without the arr1 sub-variables: const char **arr[] = { (const char *[]){ "hello", "world", NULL }, (const char *[]){ "my", "name", "is", NULL }, (const char *[]){ "i'm", "beginner", "point", "makes", NULL }, NULL, }; (which looks better when formatted on multiple lines).
|
8

Unlike my initial assessment, it can be done with a single literal.

#include <stdio.h>

int main()
{
    char* arr[3][4] = {
      {"hello", "world"},
      {"my", "name", "is"},
      {"i'm", "beginner", "point", "makes"}
    };

    printf ("%s", arr[2][3]);
    return 0;
}

Arrays 1 and 2 will be padded by zeroes at the end to be of length 4.

output:

makes

Tested it here: http://ideone.com/yDbUuz

2 Comments

Note that you're technically allocating more char** pointers than actually needed, and you don't initialize them. Is this C-standard compliant or compiler tolerated ?
@zakinster, I don't have my copy of the standard handy, but it's tested on gcc with strict warnings. I'm pretty sure it's standard compliant, one-dimensional arrays are zero padded to fill length constraints, I don't see why it won't translate to higher dimensions. As for the extra memory, it kind of depends on the data. Your approach will require an extra pointer for every array regardless of the number of pointers in it. Mine will require less NULL pointers for certain arrays length distributions. But this approach is mostly anecdotal, anyway.

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.