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

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

char *strcat406(char *str1, char *str2) {

    int str1length = 0;
    int str2length = 0;
    char newStr[str1length + str2length];
    int i;

    for (i = 0; i < str1[i] != '\0'; i++)
        str1length += 1;

    for (i = 0; i < str2[i] != '\0'; i++)
        str2length += 1;

    for (i = 0; i < str1[i] != '\0'; i++)
        newStr[i] = str1[i];

    for (i = i; i < str2[i] != '\0'; i++)
        newStr[i] = str2[i];

    return newStr;

}

Я считаю, что код должен работать, за исключением строки, которая читает return newStr;, Xcode выдает мне ошибку, которая гласит: «возвращен адрес памяти стека, связанный с локальной переменной (x)», и я думаю, что именно поэтому я не печатаю массив строк в основном, как я хочу.

Из моего исследования кажется, что это происходит потому, что память для возвращаемого массива освобождается, и поэтому я получаю результат, который мне не нужен, хотя я не нашел ни одного ответа на этом сайте или даже в документации C, которая работал на меня.

Как я могу изменить свою функцию, чтобы она возвращала конкатенацию двух строк?


person Omar N    schedule 15.04.2016    source источник
comment
though I have not found a single answer on this site or even in the C manual that has worked for me....скажите, почему я не верю в это...   -  person Sourav Ghosh    schedule 15.04.2016
comment
Я не понимаю твоего вопроса.   -  person Omar N    schedule 15.04.2016
comment
Ваш последний цикл for остановится слишком рано.   -  person Jongware    schedule 15.04.2016


Ответы (2)


Вы должны вычислить длину результирующей строки, затем выделить для нее память, затем скопировать ее, затем вернуть. Теперь вы используете VLA. Лучше использовать malloc:

char *strcat406(char *str1, char *str2) {

    int str1length = 0;
    int str2length = 0;
    char *newStr;  // note: length not known yet
    int i, j;

    for (i = 0; i < str1[i] != '\0'; i++)
        str1length += 1;

    for (i = 0; i < str2[i] != '\0'; i++)
        str2length += 1;

    newstr= malloc (str1length + str2length + 1);

    for (i = 0; str1[i] != '\0'; i++)
        newStr[i] = str1[i];

    for (j = 0 ;str2[j] != '\0'; j++)
        newStr[i+j] = str2[j];

    newstr[i+j]= '\0';
    return newStr;
}

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

EDIT Лучший подход:

char *strcat406(char *str1, char *str2)
{
    char *newStr= malloc(strlen(str1)+strlen(str2)+1);
    strcpy(newStr,str1);
    strcat(newStr,str2);
    return newStr;
}
person Paul Ogilvie    schedule 15.04.2016
comment
Почему бы вместо циклов просто не вызывать strcpy(...); strcat(...)? - person alk; 15.04.2016
comment
@alk, как я уже сказал: есть лучшие способы сделать это, но я придерживаюсь вашего подхода. Таким образом, он узнает, что было не так с его первоначальным подходом. - person Paul Ogilvie; 15.04.2016

Две вещи, чтобы сказать

  • Не полагайтесь на VLA, так как они являются дополнительной частью стандарта C11.
  • VLA не нужно размещать в куче памяти, по крайней мере, стандарт ничего не предписывает.

Простое решение: (я не проверял задействованную логику конкатенации)

Сделайте newStr указателем и используйте динамическое выделение памяти[ malloc()/ calloc()].

Динамически выделенная память остается в области действия до тех пор, пока не будет освобождена программно, поэтому они не ограничены областью действия функции, в которой они определены. В вызывающей функции вам нужно освободить память после того, как вы закончите с ней.

person Sourav Ghosh    schedule 15.04.2016