C/C++ How to Copy a Multidimensional Char Array Without Nested Loops

using C copy a 1D char array into 2D char array

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;
}

How to copy string from a single dimensional array to 2d array in c?

You are using

strcpy(answers[i][j],v[i]);

but, neither answers[i][j] nor v[i] is a string (or, pointer to a char array). You're essentially accessing out of bound memory, thereby invoking undefined behaviour.

Solution: You can simply use the assignment operator =, to copy each element one by one.

That said, if you want to use the answers[i] as string, (as seen in printf("\n%s",answers[i]);) you need to make sure it's null-terminated. A quick way of achieving that would be to initialize the array to 0 upon definition.

Something like

 char answers[10][10] = {0};  // ensure the elements are zero-initialized

Copy from 2d dynamic char array to another 2d dynamic array in c

What is wrong with this code?

The first and last parameters of the function call.

Change this:

memcpy(&buf_copy[i], buf[i], sizeof(buf[i]));

to this:

memcpy(buf_copy[i], buf[i], 33);

since you need to give the size of the column, not the size of a pointer!

Moreover, notice that you need to pass buf_copy, just like you did for buf, without taking the address of it or something, since memcpy() expects pointers for its two first parameters, and buf_copy[i] and buf[i] are pointers already.

Is there a way to do it without use of iteration?

It cannot be done without ireation because malloc() may not have returned contigeous memory. Read more in C / C++ How to copy a multidimensional char array without nested loops?


PS: Unrelated to your problem, but in general: Do I cast the result of malloc? No!

How to copy multi-dimensional char array into char *

Let assume that the actions are done consequently, i.e. first you already done this:

std::string result;
for (int i=0; i < 2; i++)
for (int j=0; j < len; j++)
result.push_back(Array[i][j]);

then you have already a char* array stored inside std::string.

char  *string = new char[result.size()];
string = strdup(test1.c_str());

Now if you skip the std::string step (why, platform doesn't support it?), you rather get something like that:

char  *string = new char[string_size];   // you have to either measure it beforehand or calculate from array size

int counter = 0;
for (int i=0; i < 2; i++)
for (int j=0; j < len; j++)
string[counter++] = Array[i][j];

If that's C code, replace new expression with malloc call. And this code got flaws like you either should allocate more memory than needed or you should count length of buffer before allocating it. Extreme case is to reallocate buffer when its capacity reached. std::string does that automatically.

I don't see why this can be a problem to devise, unless you're failing to tell us something important about what you need.

In general C++ code never looks like that unless you're designing your own containers. On ISO-compatible platform you'll have std::string, on most embedded systems, e.g. Arduino, you'll have access to String class.

How do I printout a 2 dimensional char array?

Because your array is to short to keep the C string (which requires one element more to accommodate the null character) you cant use any C functions which operate on C strings.

How to print this array?:

int main(void) {
char board [5][8]={" | | ","--+--+--"," | | ","--+--+--"," | | "};
for(size_t row = 0; row < sizeof(board) / sizeof(board[0]); row++)
{
for(size_t col = 0; col < sizeof(board[0])/ sizeof(board[0][0]); col++)
printf("%c", board[row][col]);
printf("\n");
}
}

https://godbolt.org/z/4qo4rx6oY

But if you change the size of the array you can use string functions.

int main(void) {
char board [5][9]={" | | ","--+--+--"," | | ","--+--+--"," | | "};
for(size_t row = 0; row < sizeof(board) / sizeof(board[0]); row++)
printf("%s\n", board[row]);
}

strcpy and printf a multidimensional char array C

I just wrote a quick program to show the things you've asked about... loading them up at declaration, strncpy into one of them, and then printing them out.

Hope it helps

edit: I kind of hate magic numbers so I almost totally removed them

edit: I've added alternatives Tommi Kyntola and I were talking about in the comments

#include <stdio.h>
#include <string.h>

// safe string copy macro, terminates string at end if necessary
// note: could probably just set the last char to \0 in all cases
// safely if intending to just cut off the end of the string like this

#define sstrcpy(buf, src, size) strncpy(buf, src, size); if(strlen(src) >= size) buf[size-1] = '\0';

#define MSGLIMIT 10
#define MSGLENGTH 30
#define MSGFIELDS 2
#define MSGNAME 0
#define MSGTEXT 1

int main(void) {
char messages[MSGLIMIT][MSGFIELDS][MSGLENGTH] = { {"bla", "raa"},
{"foo", "bar"}
};
int i;

char *name1 = "name16789012345678901234567890";
char *text1 = "text16789012345678901234567890";

char *name2 = "name26789012345678901234567890";
char *text2 = "text26789012345678901234567890";

char *name3 = "name36789012345678901234567890";
char *text3 = "text36789012345678901234567890";

// doesn't set last char to \0 because str overruns buffer
// undocumented result of running this, but likely to just get the name2 string
// as that'll be the very next thing in memory on most systems

strncpy(messages[2][MSGNAME], name1, MSGLENGTH); // 2 because it's the next empty one
strncpy(messages[2][MSGTEXT], text1, MSGLENGTH);

// alternative suggested by Tommi Kyntola
// printf family are more complicated and so cost more cpu time than strncpy
// but it's quick and easy anywhere you have string.h and fine most of the time

snprintf(messages[3][MSGNAME], MSGLENGTH, "%s", name2);
snprintf(messages[3][MSGTEXT], MSGLENGTH, "%s", text2);

// uses the define macro at the top of the page to set the last char to \0 if
// otherwise not set by strncpy, adds a little weight but still the better option
// if performance of this section of code is important

sstrcpy(messages[4][MSGNAME], name3, MSGLENGTH);
sstrcpy(messages[4][MSGTEXT], text3, MSGLENGTH);

for(i = 0; i < 5; i++) // 5 because that's how many I've populated
printf("%s : %s\n", messages[i][MSGNAME], messages[i][MSGTEXT]);

return 0;
}

Passing a multidimensional array as an argument in C

Function memmove() takes a pointer as the first argument. While matrix[i][j] is a char, a type from integer family. Assingning an integer other than constant 0 to a pointer require a cast. Otherwise a warning is raised.

Therefore I expect that in order to copy a single char you should pass a pointer to element matrix[i][j]. Pointers are formed by applying & operator to objects.

memmove(&matrix[i][j], p + (4*i+j), 1);

however it can written far simpler, more readable and likely more optimal as:

matrix[i][j] = p[4 * i + j];

or even by copying the whole array without any loops:

memmove(matrix, p, 16);


Related Topics



Leave a reply



Submit