Łączenie dwóch łańcuchów tekstowych

Łączenie dwóch łańcuchów tekstowych
EW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 20
0

Mam za zadanko połączyć dwa łańcuchy tekstowe bez używania funkcji strcat. Napisałem funkcję i powstaje jeden połączony łańcuch ale na końcu pojawiają się losowe znaki. typu:

Kopiuj
Ala ma kotariusz3-śKľő 

Co może powodować takie coś?

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

char* sklej (char* n1, char* n2);

int main(){

  char* napis1 = "Ala ";
  char* napis2 = "ma kota";
  char *kolejny;

  printf("Dlugosc napis1 = %i\nDlugosc napis2= %i\n",strlen(napis1), strlen(napis2));
  printf("Sklejony napis: %s\n", kolejny=sklej(napis1, napis2));
  free(kolejny);
return 0;
}

char* sklej (char* n1, char* n2)
{

  int rozmiar = strlen(n1) + strlen(n2);

  char* napis3 = malloc(rozmiar*sizeof(char));



  int dlugosc_pierwszego = 0, dlugosc_drugiego = 0;
  int dlugosc_sklejonego;

  for(dlugosc_pierwszego = 0 ; n1[dlugosc_pierwszego] != '\0'; dlugosc_pierwszego++)
  {
    napis3[dlugosc_pierwszego] = n1[dlugosc_pierwszego];

  }

  dlugosc_sklejonego = dlugosc_pierwszego;

  for(dlugosc_sklejonego; n2[dlugosc_drugiego] != '\0'; dlugosc_drugiego++)
  {

    napis3[dlugosc_sklejonego] = n2[dlugosc_drugiego];
    dlugosc_sklejonego++;

  }

  return napis3;
}
kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
5

Napisy w C należy zakończyć znakiem 0 ('\0'). Wszystkie funkcje obsługujące stringi jego się spodziewają na końcu stringa, jak go nie ma to czytają dalej... i masz UB. A w rzeczywitości najczęściej po prostu drukują śmieci z pamięci aż do napotkania tego znaku.

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
3

Zapomniałeś o null terminatorze.

grzesiek51114
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2442
1

Tak na szybkości. Kiedyś napisałem takie coś:

Kopiuj
char *concat(char *first, char *second)
{
    unsigned f_length = strlen(first);
    unsigned s_length = strlen(second);

    char *result = NULL;
    if((result = (char*)malloc(f_length + s_length + 1)))
    {
        unsigned i = 0;
        for(; i < f_length; ++i) result[i] = first[i];
        for(i = 0; i < s_length; ++i) result[i + f_length] = second[i];
        result[i + f_length] = '\0';
    }
    return result;
}

Nie zapomnij zwolnić zasobu.

Xupicor
  • Rejestracja: dni
  • Ostatnio: dni
1
Kopiuj
 malloc(rozmiar*sizeof(char))

Wystarczy malloc(rozmiar + 1)

Kopiuj
`sizeof(char)` zawsze zwróci `1`, to jest gwarantowane przez standard.
`+1` bo potrzebujesz jeszcze miejsce na `\0` na końcu, które musisz oczywiście tam wstawić sam - jak już napisano.

```c
  int dlugosc_pierwszego = 0, dlugosc_drugiego = 0;
  int dlugosc_sklejonego;

Konfuzję szerzące te nazwy - przecież chodzi Ci o indeksy, a nie o długości. ;)

grzesiek51114
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2442
0

@kq, @kaczus

Zawsze można zrobić to jawnie, bo może trafisz na "niedobry" kompilator:

Kopiuj
memcpy(result,first,f_length);
memcpy(result+f_length,second,s_length);
result[s_length + f_length] = '\0';

BTW: a ciekawe czy da się jeszcze krócej.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.