0

Consider a 2D array of type char**. This array has a finite number of rows (number of substrings), but variable column length (variable substring length).

I would like to create a function that takes this array and number of rows (substrings) as parameters, and returns a single string that consists of each ordered substring (row). It it a simple concatenation. This is the opposite behaviour of this question.

I have written the following code to do so, but it only works if each substring is the same length (constant column length), and therefore I pass the maximum column length as a function parameter:

char* cat2dCharMat(char** A, int m, int n){

    char* temp = malloc((m*n+1));
    int length = 0;
    for(int i = 0; i < m;++i){
        memcpy(&temp[n*i], A[i],strlen(A[i]));
        length += (int)strlen(A[i]);
    }
    temp[length] = '\0';
    printf("Length of concatenated string is %d chars.\n",strlen(temp));
    return temp;
}

How can I make this more general to take in many columns lengths? I also wrote a main() to accompany this function for a complete, minimum, verifiable example (forgive the 2D array initialization -- I found that using array = {"hello", "world!"} did not work):

int main(void){
    char** array2 = (char**)malloc((3)*sizeof(char*));
    for(int i = 0; i < 3; ++i){
        array2[i] = (char*)malloc(4*sizeof(char));
        for(int j = 0; j < 3;++j){
            if(j==0 && i==0)
                array2[i][j] = '0';
            else if(j==1 && i==0)
                array2[i][j] = '8';
            else if(j==2 && i==0)
                array2[i][j] = '7';
            else if(j==0 && i==1)
                array2[i][j] = '4';
            else if(j==1 && i==1)
                array2[i][j] = '9';
            else if(j==2 && i==1)
                array2[i][j] = '5';
        }
    }
    char** array1 = (char**)malloc((3)*sizeof(char*));
    for(int i = 0; i < 3; ++i){
        if(i == 0){
            array1[i] = malloc(4);
            for(int j = 0; j < 3;++j){
                if(j==0 && i==0)
                    array1[i][j] = '0';
                else if(j==1 && i==0)
                    array1[i][j] = '8';
                else if(j==2 && i==0)
                    array1[i][j] = '7';
            }
        }else{
            array1[i] = malloc(5);
            for(int j = 0; j < 4;++j){
                if(j==0 && i==0)
                    array1[i][j] = '0';
                else if(j==1 && i==1)
                    array1[i][j] = '8';
                else if(j==2 && i==1)
                    array1[i][j] = '7';
                else if(j==3 && i==1)
                    array1[i][j] = '7';
            }
        }
    }
    array1[0][3] = '\0';
    array1[1][4] = '\0';
    char* array1cat = cat2dCharMat(array1,2,4);
    char* array2cat = cat2dCharMat(array2,2,3);
    printf("Testing cat2dCharMat()...\n\n");
    printf("Case 1: {\"087\",\"495\"}\n");
    printf("Expected Result: 087495\n");
    printf("Actual Result:   %s\n", array2cat);
    printf("Case 2:{\"087\",\"0877\"}\n");
    printf("Expected Result: 0870877\n");
    printf("Actual Result:   %s\n", array1cat);
    }
Community
  • 1
  • 1
Matt
  • 55
  • 1
  • 6
  • 1
    Something like `char **` is not a 2D array. A _variable length array_ is a completely different datatype. – too honest for this site Jan 24 '17 at 20:17
  • You just have an array of strings. You can iterate over it once, taking the length of each string and summing the lengths, and then allocate a buffer large enough to concatenate them together. By the way -- here is an interesting blog article which discusses the problem of concatenating a large number of strings: https://www.joelonsoftware.com/2001/12/11/back-to-basics/ (written by one of the cofounders of Stack Overflow) – John Coleman Jan 24 '17 at 20:21
  • 1) at else-block `if(j==0 && i==0)` --> `if(j==0 && i==1)` 2) `memcpy(&temp[n*i], A[i],strlen(A[i]));` --> `memcpy(&temp[length], A[i],strlen(A[i]));` – BLUEPIXY Jan 24 '17 at 20:48

1 Answers1

0

I didn't understand well the second parameter you wish for your function ("number of rows (substrings)"), so here is an idea concatenating the n first strings of your "array" (which is not an array, C: differences between char pointer and array)

Please take note that it's not an safe function at all, since it does not check the value you give to n isn't to big for your variable (it would provoke a segmentation fault); take care of this point when implementing your own function in your own code.

char * concatenate_these_strings (char ** my_strings ,unsigned int n){
    int i,size = 1;
    for ( i=0 ; i<n ; i++){
            size += strlen (my_strings[i]);
    }
    char * my_result = malloc (size);
    for ( i=0 ; i<n ; i++){
        strcat (my_result,my_strings[i]);
    }
    return my_result;
}
Community
  • 1
  • 1
m.raynal
  • 2,983
  • 2
  • 21
  • 34