I am working through a textbook teaching myself C programming using the Code::Blocks v20.03 IDE.
I am really bamboozled by a small program that is to read in three small strings into a 2d char array and then just print them out to the screen. The code for the program is shown below.
#include <stdio.h>
int main(void)
{
char *colors[3][10] = {'\0'};
printf("\nEnter 3 colors seperated by spaces: ");
scanf("%s %s %s", colors[0][0], colors[1][0], colors[2][0]);
printf("\nYour entered: ");
printf("%s %s %s\n", colors[0][0], colors[1][0], colors[2][0]);
return 0;
}
This compiles with zero errors or warnings and when executed produces the following output.
You entered: (null) (null) (null)
Using the IDE's Watches window shows that nothing is written to the array. I understand that an array name is treated as a pointer to the first element in the array. I also understand the use of subscripts/indexes to access elements within the dimensions of the array (e.g. arrays of ints) and so the need to keep the array second dimension at zero in this char array.
Sadly, this has me completely foxxed and so I need help to fill in my gap in understanding.
Best regards,
Stuart
CodePudding user response:
You have a two-dimensional array of null pointers
char *colors[3][10] = {'\0'};
So The call of scanf
printf("\nEnter 3 colors seperated by spaces: ");
scanf("%s %s %s", colors[0][0], colors[1][0], colors[2][0]);
invokes undefined behavior.
It seems you mean the following
char colors[3][10] = {'\0'};
printf("\nEnter 3 colors seperated by spaces: ");
scanf(" %9s %9s %9s", colors[0], colors[1], colors[2]);
printf("\nYour entered: ");
printf("%s %s %s\n", colors[0], colors[1], colors[2]);
CodePudding user response:
When using scanf
with the %s
specifier, you must provide a pointer to a memory address for scanf
to write to. Therefore, you must first create a memory buffer which has sufficient space for storing the entire string. The simplest way of doing this would be to declare an array of type char
.
However, the line
char *colors[3][10] = {'\0'};
will not declare an array of type char
. Instead, it will create a multidimensional array of pointers.
If you want to create an array of type char
, you can do this:
char color[10];
If you want to create an array of arrays of type char
, you can do this:
char colors[3][10];
Now you can use the line
scanf( "%s %s %s", colors[0], colors[1], colors[2] );
which is equivalent to
scanf( "%s %s %s", &colors[0][0], &colors[1][0], &colors[2][0] );
due to array to pointer decay. In most situations, if you use the name of an array in an expression, it will decay to a pointer to the first element of the array.
Note that using %s
is dangerous, because if the user types more data than fits in the memory buffer (in this case more than 9 characters), then you will have a buffer overflow, which causes undefined behavior.
Therefore, it would be safer to write it like this:
scanf( "%9s %9s %9s", colors[0], colors[1], colors[2] );
This limits the number of matched characters to 9
characters per string, so scanf
will never write more than 10
characters (9
characters plus the terminating null character) into a memory buffer.
CodePudding user response:
You are not derefencing the array element you want. colors[0][0]
returns the value in that element of the array, not a pointer to it. Try &colors[0][0]
instead.