0

So would like to create an 2D array of characters for testing purposes. Here is my code.

    const int rows = 4;
    const int columns = 6;
    //char field[rows][columns];
    //fill_field(rows,columns,field);
    char field[rows][columns] = {
                            "A BCD ",
                            "B CDA ", 
                            "C DAB ", 
                            "D ABC "
                            };

I'm getting error saying "variable-sized object may not be initialized" and "excess elements in array initializer" for every string i have typed.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
tomastrue
  • 11
  • 2
  • `char field[rows][]` if you're planning to change the contents, `char* field[rows]` otherwise. –  Nov 23 '22 at 14:23
  • For 6 characters of columns you must allocate 6 chars + 1 for the NULL termination. Hence columns must be 7. – Kozmotronik Nov 23 '22 at 14:23
  • Regarding error 1, see [How to declare variable-length arrays correctly?](https://software.codidact.com/posts/283440). Regarding error 2, study how strings work in C as per the linked duplicate. – Lundin Nov 23 '22 at 15:44

3 Answers3

1

For starters if you want that the array would contain strings then columns must be set to 7. Otherwise the terminating zero character '\0' of the strings used as initializers will not be stored in the array. As a result the array will not contain strings.

This declaration

const int rows = 4;
const int columns = 6;
//char field[rows][columns];
//fill_field(rows,columns,field);
char field[rows][columns] = {
                        "A BCD ",
                        "B CDA ", 
                        "C DAB ", 
                        "D ABC "
                        };

declares a variable length array because the variables rows and columns are not integer constant expressions according the C Standard. From the C Standard (6.6 Constant expressions)

6 An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

and (6.7.6.2 Array declarators)

4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope; such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)

Such arrays may not be initialized in their declarations. From the C Standard (6.7.9 Initialization)

3 The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

Instead you could write for example

enum { rows = 4, columns = 7 };
//char field[rows][columns];
//fill_field(rows,columns,field);
char field[rows][columns] = {
                        "A BCD ",
                        "B CDA ", 
                        "C DAB ", 
                        "D ABC "
                        };

Pay attention to that instead of the two-dimensional array you could declare an array of pointers to string literals like for example

const char * field[] = { "A BCD ", "B CDA ", "C DAB ", "D ABC " };

const size_t N = sizeof( field ) / sizeof( *field );

provided that you are not going to change the strings.

To access characters of the string literals you can use expressions with similar subscript operators as for two-dimensional arrays like for example

for ( size_t i = 0; i < N; i++ )
{
    for ( size_t j = 0; field[i][j] != '\0'; j++ )
    {
        putchar( field[i][j] );
    }
    putchar( '\n' );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

if the sizes are not constant expressions the array becomes a Variable Length Array (VLA) and such objects cannot be initialized.

const int is not a constant expression.

You need to change variable definitions to macros

#define rows 4
#define columns 6

https://godbolt.org/z/sYT8K8rva

0___________
  • 60,014
  • 4
  • 34
  • 74
-1

Four ways that work. Pick the syntax you prefer... I just compiled them.

int main()
    {
        char field[4][6] = {
                               {'A',' ','B','C','D',' '},
                               {'B',' ','C','D','A',' '},
                               {'C',' ','D','A','B',' '},
                               {'D',' ','A','B','C',' '},
        };
    
        char fieldWithNulls[4][7] = {
                               {'A',' ','B','C','D',' ', 0},
                               {'B',' ','C','D','A',' ', 0},
                               {'C',' ','D','A','B',' ', 0},
                               {'D',' ','A','B','C',' ', 0},
        };

        char fieldWithNullsAndStrings[][7] = {
                          {"A BCD "},
                          {"B CDA "},
                          {"C DAB "},
                          {"D ABC "},
        };

       char fieldWithNullsAndStrings2[][7] = {
                      "A BCD ",
                      "B CDA ",
                      "C DAB ",
                      "D ABC ",
       };
    }

Obviously you can tweak these how you want. The question doesn't really say what all the requirements are just that what he is doing doesn't work.

Also you can drop the first array size as the compiler can work it out given the column size, like:

char fieldWithNulls[][7] = {

The last three arrays contain a zero terminator so can be treated as c strings. They also are identical in memory once compiled. Choose the syntax you prefer for what you are doing.

AnthonyLambert
  • 8,768
  • 4
  • 37
  • 72
  • Not my down vote but likely because the answer doesn't even try to explain "I'm getting error saying "variable-sized object may not be initialized"". – Lundin Nov 23 '22 at 15:47