I am trying to copy a 1D array of Strings into a 2D array of strings in C.
I was able to achieve this with integer enter image description here
//Here is what I tried for integers.
int main()
{
int arr[3][3];
int arr2[9]={1,2,3,4,5,6,7,8,9};
int i,j,k=0;
for(i=0; i<3;i ){
for(j=0; j<3;i ){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
for(i=0; i<3; i ) {
for(j=0; j<3; j )
printf("- ", arr[j][i]);
printf("\n");
}
return 0;
}
I changed my data to char and I tried to run the same code I got a segmentation error. Here is what I have tried so far and it didnt work. error :Segmentation fault (core dumped)
#include<stdio.h>
#include<string.h>
int main()
{
char *d[3][3]; // Destination array
char *s[9]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i ){
for(j=0; j<3;i ){
strcpy(d[j][i], s[i]);
}
}
for(i=0; i<3; i ) {
for(j=0; j<3; j )
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
I have made some adjustment and now it print some weird strings
#include<stdio.h>
#include<string.h>
int main() {
char d[3][3] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i ){
for(j=0; j<3;j ){
d[j][i] = *s[i];
}
}
for(i=0; i<3; i ) {
for(j=0; j<3; j )
printf("%s ", &d[j][i]);
printf("\n");
}
return 0;
}
CodePudding user response:
This for loop
for(i=0; i<3;i ){
for(j=0; j<3;i ){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
is incorrect. In the inner loop there are used the same elements arr2[i]
where i
is changed from 0
to 2
inclusively.
You need to write
for(i=0; i<3;i ){
for(j=0; j<3;i ){
arr[j][i] = arr2[ 3 * i j];
}
}
Another way to write loops is the following
for ( i = 0; i < 9; i )
{
arr[i / 3][i % 3] = arr2[i];
}
As for arrays of pointers of the type char * then the nested loops will look similarly
for(i=0; i<3;i ){
for(j=0; j<3;i ){
d[i][j] = s[ 3 * i j];
}
}
provided that the array s is declared like
char * s[9]={"orange","apple","table","chair","cable","TV", "124","HI"};
And to output the result array you need to write
for(i=0; i<3; i ) {
for(j=0; j<3; j )
printf("%s ", d[i][i]);
^^^^^^^
printf("\n");
}
As for your last program then it can look like
#include<stdio.h>
#include<string.h>
int main( void )
{
char d[3][3][8] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
for( size_t i = 0; i < 3; i )
{
for ( size_t j = 0; j < 3;j )
{
strcpy( d[j][i], s[3 * i j] );
}
}
for ( size_t i = 0; i < 3; i )
{
for ( size_t j = 0; j < 3; j )
{
printf( "%s ", d[i][j] );
}
putchar( '\n' );
}
return 0;
}
CodePudding user response:
There's numerous big problems here.
You could have simply solved this with
memcpy(arr, arr2, sizeof *arr2);
(Probably the least of your problems, but...) This is badly written performance-wise:
for(j=0; j<3;i ){ arr[j][i] = arr2[i];
Multiple loops should always have the inner-most loop work with the inner-most array item, in this case it should have beenarr[i][j]
, or you get needlessly bad data cache performance.for(j=0; j<3;i )
How aboutj
.char *d[3][3];
is an uninitialized 2D array of pointers, each pointing at la-la-land. So you can't copy jack into those addresses - pointers need to point at valid, allocated memory.char d[3][3]
is a 2D array of 3x3 characters, so it can't contain the data you wish to store there, let alone the mandatory null terminators required for strings to work.char *s[9] = ...
In case you meant the 9th item to be NULL, a so-called sentinel value, you should type outNULL
explicitly or otherwise the reader can't tell if aNULL
sentinel is intended or if you just sloppily added one by accident.As you can tell from previous comments, the overall slopiness is a recurring major problem here. Take for example:
for(j=0; j<3; j ) printf("%s ", &d[j][i]); printf("\n");
Because of sloppy indention, we can't tell if the
printf("\n");
was intended to sit inside the inner loop or not (it is not, despite the indention). You can't just type some almost correct stuff down in a hurry. You have to carefully type down actually correct code. There's various myths that great programmers are smart, great at math or abstract thinking etc - in reality, great programmers are careful and disciplined, taking some pride in their own craft.
The quick & dirty fix is to use the second example char* d[3][3]
and then instead of strcpy
use strdup
(currently non-standard, soon to become standard):
for(size_t i=0; i<3; i ){
for(size_t j=0; j<3; j ){
d[i][j] = strdup(s[i]);
}
}
(And ideally also call free()
for each item in d
at the end.)
But the root problem here is that you need to go back and carefully study arrays, pointers and strings, in that order, before using them.
CodePudding user response:
Some issues ...
d
is unitialized so the pointers within point to random locations.To fix, we need to use
malloc
to get space and then dostrcpy
. An easier way is to just usestrdup
. Or, just assign thes
value directly.Your
j
loop should incrementj
and noti
.Using
s[i]
will repeat after three elements. To fix, we can do:s[k ]
You are short one initializer for
s
(i.e. it is length 9 but you have only 8 strings).
Here is the refactored code:
#include <stdio.h>
#include <string.h>
int
main(void)
{
char *d[3][3]; // Destination array
char *s[9] = {
"orange", "apple", "table", "chair", "cable", "TV", "124", "HI",
#if 1
"raindrops"
#endif
}; // Source 1 Day array
int i, j, k = 0;
for (i = 0; i < 3; i ) {
for (j = 0; j < 3; j ) {
// NOTE/BUG: we must allocate space for d[j][i]
#if 0
strcpy(d[j][i], s[i]);
#else
d[j][i] = strdup(s[k ]);
#endif
}
}
for (i = 0; i < 3; i ) {
for (j = 0; j < 3; j )
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
Here is the output:
orange apple table
chair cable TV
124 HI raindrops