How do I concatenate the string elements of my array into a single string in C?

Deadly 提交于 2019-12-02 14:51:42
#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;
}

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.

Michel Billaud

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!