Конкатенация строк в C с помощью указателей

Рейтинг: 4Ответов: 1Опубликовано: 20.08.2023

Я хочу написать функцию, которая делает конкатенацию строк в C. При этом мне хотелось бы это реализовать при помощи указателей. Я написал вот этот код:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
char* concat(char* a, char* b) { //функция конкатенации
    char* c = (char*) malloc(sizeof(char)*(strlen(a)+strlen(b)+1)); //выделение памяти для новой строки
    for (int i = 0; i < strlen(a); i++){ //задать первым символам результатирующей строки символы первой строки
        c[i] = a[i];
    }
    for (int i = strlen(a); i < strlen(a)+strlen(b); i++){//задать следующим символам результатирующей строки символы второй строки
        c[i] = b[i];
    }
    c[strlen(a)+strlen(b)] = '\0'; //добавить нулевой символ
    return c;
}


int main(){ //проверка
    char* a = concat("Hello, ", "world!");
    for (int i = 0; i < strlen(a); i++){ //распечатка
        printf("%c", a[i]);
    }
    free(a); //освобождение памяти
    return 0;
}

Но, к сожалению, он работает не так, как нужно. Он выводит:

Hello, Hello, 

Как сделать так, чтобы он не дублировал первую строку, а склеивал две разные?

Ответы

▲ 5Принят

Посмотрим на вот это:

for (int i = strlen(a); i < strlen(a)+strlen(b); i++){
    c[i] = b[i];
}

Что получается? Вы берете символы из строки b, но первым символом берете тот, который расположен с индексом, равным длине строки a, а не является первым символом b. То, что при этом вы попали на строку a (ее дублирование) — просто случайность, UB.

Вот один вариант

c[i] = b[i - strlen(a)];

вот другой

for (int j = 0, i = strlen(a); i < strlen(a)+strlen(b); i++){
    c[i] = b[j++];
}

Но проще переписать всю функцию так:

char* concat(const char* a, const char* b) {
    char* c = malloc(strlen(a)+strlen(b)+1);
    int i,j = 0;
    while(c[i] = a[i]) ++i;
    while(c[i++] = b[j++]);
    return c;
}

const в С хоть и необязателен, но желателен (вы же не меняете входные строки), приведение результата malloc к типу char* обязательно в С++, но не в С, ну и sizeof(char) равно 1 по определению...

Ну и главное потом — не забыть освободить выделенную память...