Конкатенация двух массивов строк?

Я новичок в мире c, и я хочу объединить два массива в один массив, у меня есть одна идея, как это сделать, но это не работает:P

char *s_one[] = { "Zorro", "Alex", "Celine" };
char *s_two[] = { "Zorro1", "Alex1"};

char *p = (char*)malloc((sizeof(s_one)+sizeof(s_two))*sizeof(char));
memcpy(p, s_one, sizeof(s_one));
memcpy(p + sizeof(s_one), s_two, sizeof(s_two));

//print out
for (count = 0; count < sizeof(p); count++)
        printf("\narr[%d] = %c.", count, p[count]);

на выходе просто некоторые случайные символы... что я делаю не так, заранее спасибо за каждый совет

вывод должен быть: Зорро Алекс Селин Зорро1 Алекс1

5 ответов

Решение

Вместо использования memcpy я бы порекомендовал перебрать каждый из двух массивов и скопировать одну строку из исходного массива в p с помощью strcpy. Проблема memcpy в том, что он не должен копировать символ \0, следовательно, ваши случайные символы.

У вас инструкция malloc в порядке.

Посмотрим, смогу ли я понять это правильно...

s_one это массив char *, Так что ваши sizeof() а также memcpy() операции, скорее всего, работают с указателями, а не со строками, на которые они указывают где-то еще в памяти. Затем, когда вы идете и printf() Вы печатаете указатели как символы, а не строки, на которые они указывают (как строки). Не уверен здесь, но, возможно, это будет работать?

printf("\narr[%d] = %s.", count, *p[count]);

Если вы не исправите это до того, как я вернусь домой, я проверю это и посмотрю.


Объедините с комментарием Марво о sizeof() звонки.


Это действительно зависит от того, что вы хотите, но вот моя попытка, так как я сказал, что опубликую это:

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

int main(void)
{
    char *s_one[] = { "Zorro", "Alex", "Celine" };
    char *s_two[] = { "Zorro1", "Alex1"};

    printf("%lu\n", sizeof(s_one));
    printf("%lu\n", sizeof(s_two));

    int numberOfEntries = (sizeof(s_one) + sizeof(s_two)) / sizeof(char*);
    char **p = (char **)malloc(numberOfEntries);

    printf("%d\n", numberOfEntries);

    memcpy(p, s_one, sizeof(s_one));
    memcpy(p + sizeof(s_one)/sizeof(char *), s_two, sizeof(s_two));

    //print out
    int count = 0;
    for (count = 0; count < numberOfEntries; count++)
        printf("arr[%d] = %s.\n", count, p[count]);
}

У вас есть два массива указателей на char (фактически указывает на первый символ 0-оканчивается char[]). Итак, когда вы memcpy от s_one а также s_two в pВы копируете указатели, и то, что вы распечатываете, является частью значений указателя.

Если вы объявили

char **p = malloc(sizeof s_one + sizeof s_two);

вы получите массив из пяти char*, указывая на соответствующие строки.

Если вы хотите объединить строки, что элементы s_one соответственно s_two указывает на то, что вам нужно выделить достаточно для хранения результата (плюс 0-терминатор):

size_t needed = 1;
for(size_t i = 0; i < sizeof s_one / sizeof *s_one; ++i)
    needed += strlen(s_one[i]);
for((size_t i = 0; i < sizeof s_two / sizeof *s_two; ++i)
    needed += strlen(s_two[i]);
char *p = malloc(needed);
if (!p) {
    // allocation failed
    exit(EXIT_FAILURE);
}
p[0] = 0;
for(size_t i = 0; i < sizeof s_one / sizeof *s_one; ++i)
    strcat(p,s_one[i]);
for(size_t i = 0; i < sizeof s_two / sizeof *s_two; ++i)
    strcat(p,s_two[i]);

Всего два совета для менее шумного malloc:
Вам не нужно приводить это возвращаемое значение.
Вам не нужен sizeof(char), поскольку char по определению составляет 1 байт.

Мое первое решение - перебрать каждый из двух массивов и скопировать одну строку из исходного массива в p, используя strcpy... благодаря Эрнану Веласкесу

char *s_one[] = { "Zorro", "Alex", "Celine" };
char *s_two[] = { "Zorro1", "Alex1"};

char *p[sizeof(s_one)/sizeof(char *) + sizeof(s_two)/sizeof(char *)];
memset(p, 0, sizeof(p));
for(count=0;count < sizeof(s_one)/sizeof(char *) ;count++) {
    p[count] = (char*)malloc((strlen(s_one[count])+1)*sizeof(char));
    strcpy(p[count], s_one[count]);
}
i=count;
for(count=0;count < sizeof(s_two)/sizeof(char *) ;count++) {
    p[i] = (char*)malloc((strlen(s_two[count])+1)*sizeof(char));
    strcpy(p[i], s_two[count]);
    i++;
}

//print out
for (count = 0; count < sizeof(p)/sizeof(char *); count++)
        printf("\narr[%d] = %s.", count, p[count]);

я думаю, что это не очень чисто, но это работает для меня... завтра я попробую это с подсказкой от Даниэля Фишера

Другие вопросы по тегам