2

I have an array of strings and I would like to create a new string that is a concatenation of all the array elements. Any help is appreciated, thanks

1
  • 7
    A loop and the strcat function? Commented Sep 10, 2014 at 14:21

3 Answers 3

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

char *concatenate(size_t size, char *array[size], const char *joint){
    size_t jlen, lens[size];
    size_t i, total_size = (size-1) * (jlen=strlen(joint)) + 1;
    char *result, *p;


    for(i=0;i<size;++i){
        total_size += (lens[i]=strlen(array[i]));
    }
    p = result = malloc(total_size);
    for(i=0;i<size;++i){
        memcpy(p, array[i], lens[i]);
        p += lens[i];
        if(i<size-1){
            memcpy(p, joint, jlen);
            p += jlen;
        }
    }
    *p = '\0';
    return result;
}

int main(){
    char *ss[] = { "first", "second", "last" };
    char *cat = concatenate(3, ss, "");
    puts(cat);
    free(cat);
    cat = concatenate(3, ss, ", ");
    puts(cat);
    free(cat);
    return 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

To drop quite a bit of code from this, you could change the malloc(total_size) to calloc(total_size, 1) and then use strcat instead of memcpy. That way you don't need to track the location in the buffer with p- you can directly strcat to result. You can also then get rid of the explicit NULL terminating statement
3

There are two possible interpretations of your question:

  1. To fill a destination char array with the concatenation, or
  2. To (m)allocate a new (big enough) string and fill it with the concatenation

The second problem can obviously be reduced to the first one:

 char *concatenation_of(char *strings[], size_t number) {

     size_t sum;
     for (size_t i = 0; i < number; i++) {
           sum += strlen(strings[i]);
     }

     return strcatarray(malloc(sum + 1), strings, number);
 } 

So let's focus now on the concatenation of an array of strings into a destination area.

The naive version, using strcat:

char *strcatarray(char * dest, char *strings[], size_t number)
{
     dest[0] = '\0';
     for (size_t i = 0; i < number; i++) {
         strcat(dest, strings[i]);
     }
     return dest;
}

Despite its simplicity, this has a major drawback: the destination string gets larger and larger, and it takes more and more time to find where to append the next strings[i]. This is also a quadratic algorithm.

A small and easy fix is to keep the address of the terminating null char, and append there:

char *strcatarray(char * dest, char *strings[], size_t number) {
    char *target = dest;               // where to copy the next elements
    *target = '\0';
    for (size_t i = 0; i < number; i++) {
        strcat(target, strings[i]);
        target += strlen(strings[i]);   // move to the end
    };
    return dest;
}

Lastly, if you wish to "join" the string elements with some glue:

char *strjoinarray(char * dest, char *strings[], size_t number, char * glue) {
    size_t glue_length = strlen(glue);

    char *target = dest;               // where to copy the next elements
    *target = '\0';
    for (size_t i = 0; i < number; i++) {
        if (i > 0) {                   // need glue
            strcat(target, glue);
            target += glue_length;
        }
        strcat(target, strings[i]);
        target += strlen(strings[i]);   // move to the end
    };
    return dest;
}

Comments

1

First of all make sure that the destination size if at least one more than, the size of all
the strings in the array taken together, otherwise you will end up writing the strings at
some random memory address which will not be accessible to you, and you might end up having
a segmentation fault.
Its better to use "strncat" than "strcat", the former will enable you to copy only the
intended number of bytes. Do not forget to append a null terminator after all the strings have been copied successfully.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.