user3706129
user3706129

Reputation: 229

Initialize 2d array of chars

Im trying to initialize 2d array of chars with this ode

int x=4;
int y=4;
char plg[x][y]={{"o","o","o","o"},{"o","o","o","o"},{"o","o","o","o"},{"o","o","o","o"}};

but this piece of code throws error error: excess elements in char array initializer| i was searching for a while and everything says this is the rigth method how to do 2d char array. Why does it throw error?

Upvotes: 1

Views: 3077

Answers (4)

chqrlie
chqrlie

Reputation: 144780

In C you cannot use dynamic expressions as array sizes for global variables. It is possible for local variables since the C99 Standard, but these arrays known as VLA cannot be initialized.

For your purpose, you must specify the size directly with literal constants or constant expressions. You can use macros to increase readability, but it is a bad idea to #define x 4 as short identifiers like x may be used elsewhere in your program and will be substituted as well, leading to obscure bugs.

You cannot initialize the 2D array of char with a string for each individual char, you can either use character literals this way:

char plg[4][4] = {
    {'o','o','o','o'},
    {'o','o','o','o'},
    {'o','o','o','o'},
    {'o','o','o','o'}
};

Or you can use string literals to initialize the last level of the array:

char plg[4][4] = {"oooo", "oooo", "oooo", "oooo" };

Note that although you can elide the inner braces with char literal initializers this way:

char plg[4][4] = {'o','o','o','o','o','o','o','o','o','o','o','o','o','o','o','o' };

It is not possible to coalesce string initializers this way:

char plg[4][4] = { "oooooooooooooooo" }; // warning: initializer-string for char array is too long

The syntax above only initializes the first subarray with 'o's, leaving the remaining 3 initialized with '\0's

If you really need for the sizes to be dynamic, you will need to initialize the array some other way:

void myfunc(int x, int y) {
    char plg[x][y];
    int scores[x][y];

    // you can initialize char arrays this way
    memset(plg, 'o', sizeof(plg));

    // you need a loop for other types
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            scores[i][j] = 1;
        }
    }
    ...
}

You still need to be careful with this feature: you must check user input a avoid allocating too much data in automatic storage (aka on the stack). Sufficiently large or possibly negative values of x or y will invoke undefined behavior. Only small values should be allowed, typically less than 256. For a more general solution, you will need to allocate plg from the heap.

Upvotes: 5

tdao
tdao

Reputation: 17668

Usually you need to define rows and cols when declaring a matrix, such as:

#define N_ROWS 4
#define N_COLS 4

char plg[N_ROWS][N_COLS]={{'o','o','o','o'},{'o','o','o','o'},{'o','o','o','o'},{'o','o','o','o'}};

Now if you need rows and cols as input variables, you need to dynamically allow the array. For example,

#include <stdlib.h>
#include <string.h>

int x = 4;
int y = 4;
char **plg = malloc(sizeof(char *) * x);
int i = 0;
for( i = 0; i < x; i++ )
{
    plg[i] = malloc(sizeof(char) * (y + 1));    // +1 for NULL terminator
}

for( i = 0; i < x; i++ )
{
    strcpy( plg[i], "oooo" );
    printf( "%s \n", plg[i] );
}

Upvotes: 1

Kai
Kai

Reputation: 5910

#define N_ROWS 4
#define N_COLS 4

you have to replace " with ' (single) cause it's not string but chars:

char plg[N_ROWS][N_COLS]={{'o','o','o','o'},{'o','o','o','o'},{'o','o','o','o'},{'o','o','o','o'}};

moreover the initializers have to be definied during compile time not during runtime otherwise it would be a dynamic array for which you need to allocate memory manually.

Upvotes: 2

Karoly Horvath
Karoly Horvath

Reputation: 96266

"this is a string"

and

'o' /* this is a character */

Upvotes: 3

Related Questions