I want to write a function that copies an array of different column numbers. My current code can only copy arrays with a fixed number of columns. How can I modify my code so that functions can copy arrays with the different numbers of columns?
My idea is to provide different column number information in the parameter list, but I am not sure how to implement it.
#include <stdio.h>
#include <stdlib.h>
// simple program to copy a 2d array of numbers
int **array_copy2d(int **src, int rows, int cols) {
// allocate
int **result = malloc(sizeof(int*) * rows);
if (result == NULL) {
return NULL;
}
// copies from src to dest array.
for (int row = 0; row < rows; row ) {
// allocate a row
result[row] = malloc(sizeof(int) * cols);
if (result[row] == NULL) {
return NULL;
}
// copy a row.
for (int col = 0; col < cols; col ) {
result[row][col] = src[row][col];
}
}
return result;
}
// driver code for array copy
int main(void) {
// declare and build 2d array
int rows = 3;
int cols = 2;
int row0[] = { 1, 2 };
int row1[] = { 3, 4 };
int row2[] = { 5, 6 };
int *vals[3];
// build vals
vals[0] = row0;
vals[1] = row1;
vals[2] = row2;
// destination array
int **val_copy;
// copy
val_copy = array_copy2d(vals, rows, cols);
// check if malloc worked
if (val_copy == NULL) {
printf("allocation error\n");
return 1;
}
// test
for (int row = 0; row < rows; row ) {
for (int col = 0; col < cols; col ) {
printf("%d ", val_copy[row][col]);
}
printf("\n");
}
return 0;
}
Test sample:
1 2
3 4
5 6
Thank you all for your help.
CodePudding user response:
My idea is to provide different column number information in the parameter list
Take a look to Variadic functions
But notice that in this case, you can use the first element of the array as sentinel:
int row0[] = {2, 1, 2}; // 2 elements
int row1[] = {3, 3, 4, 5}; // 3 elements
int row2[] = {1, 6}; // 1 element
Then, your function can look like:
int** array_copy2d(int **src, int rows) {
// allocate
int** result = malloc(sizeof(int*) * rows);
if (result == NULL) {
return NULL;
}
// copies from src to dest array.
for (int row = 0; row < rows; row ) {
// allocate a row
int cols = src[row][0 1]; // Get the sentinel value
result[row] = malloc(sizeof(int) * cols);
if (result[row] == NULL) {
return NULL;
}
// copy a row.
for (int col = 0; col < cols; col ) {
result[row][col] = src[row][col];
}
}
return result;
}
Now you don't need to pass the number of columns, in main
, switch to
val_copy = array_copy2d(vals, rows);
But remember to skip the first element in the printing loop:
for (int row = 0; row < rows; row ) {
int cols = val_copy[row][0];
for (int col = 1; col <= cols; col ) {
printf("%d ", val_copy[row][col]);
}
printf("\n");
}
CodePudding user response:
int rows, cols;
scanf("%d%d", &rows,&cols);
int **vals = malloc(sizeof(int*)*rows);
for(int row=0; row<rows; row ){
vals[row] = malloc(sizeof(int*)*cols);
for(int col=0; col<cols; col ){
scanf("%d", &vals[row][col]);
}
}
int **val_copy = malloc(sizeof(int*)*rows);
val_copy = array_copy2d(vals, rows, cols);
if (val_copy == NULL) {
printf("allocation error\n");
return 1;
}
for (int row = 0; row < rows; row ) {
for (int col = 0; col < cols; col ) {
printf("%d ", vals[row][col]);
}printf("\n");
}
CodePudding user response:
Your current code can copy a submatrix: the number of rows and columns in the destination matrix must be less or equal to the number of rows and columns in the source matrix.
You can modify the code to allow for larger numbers if you pass the dimensions of the source and destination matrices separately.
If you want to handle jagged arrays, ie: if the number of columns in the source matrix varies from one row to the next, the row widths must be passed separately, as an array.
Here is a modified version for arbitrary sizes:
#include <stdio.h>
#include <stdlib.h>
// simple program to copy a 2d array of numbers
int **array_copy2d(int row1, int col1, int **src, int rows, int cols) {
// allocate
int **result = calloc(sizeof(int*), rows1);
if (result == NULL) {
return NULL;
}
for (int row1 = 0; row < rows1; row ) {
// allocate a row
result[row] = calloc(sizeof(int), cols1);
if (result[row] == NULL) {
return NULL;
}
}
// copies from src to dest array.
if (rows > rows1)
rows = rows1;
if (cols > cols1)
cols = cols1;
for (int row = 0; row < rows; row ) {
// copy a row.
for (int col = 0; col < cols; col ) {
result[row][col] = src[row][col];
}
}
return result;
}
// driver code for array copy
int main(void) {
// declare and build 2d array
int rows = 3;
int cols = 2;
int row0[] = { 1, 2 };
int row1[] = { 3, 4 };
int row2[] = { 5, 6 };
int *vals[3] = { row0, row1, row2 };
// destination array
int **val_copy;
// copy
val_copy = array_copy2d(2, 4, vals, rows, cols);
// check if malloc worked
if (val_copy == NULL) {
printf("allocation error\n");
return 1;
}
// test
for (int row = 0; row < 2; row ) {
for (int col = 0; col < 4; col ) {
printf("%d ", val_copy[row][col]);
}
printf("\n");
}
return 0;
}
Output:
1 2 0 0
3 4 0 0