Home > Software engineering >  Copy 2d array which have different columns in c
Copy 2d array which have different columns in c

Time:06-01

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
  •  Tags:  
  • c
  • Related