• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Funkcja strcpy

Object Storage Arubacloud
0 głosów
269 wizyt
pytanie zadane 18 stycznia 2023 w C i C++ przez Zuzan Początkujący (390 p.)

Witam. Mam do wykonania takie zadanie: 

Napisz własne odpowiedniki funkcji strcpy, strcat oraz strlen. Użyj modyfikatorów const w liście parametrów.

Prototypy funkcji mają wyglądać następująco:

char* my_strcpy(char* dest, const char* src);
  • src - wskaźnik na tablicę znaków, skąd ma zostać skopiowany tekst,
  • dest - wskaźnik na tablicę znaków, do której ma zostać skopiownay tekst.
  • Funkcja zwraca NULL, jeśli nie można wykonać operacji, w przeciwnym wypadku funkcja ma zwrócić wskaźnik dest.
char* my_strcat(char* dest, const char* src);
  • src - wskaźnik na tablicę znaków, skąd ma zostać skopiowany tekst,
  • dest - wskaźnik na tablicę znaków, do której ma zostać doklejony tekst.
  • Funkcja zwraca NULL, jeśli nie można wykonać operacji, w przeciwnym wypadku funkcja ma zwrócić wskaźnik dest.
int my_strlen(const char* str);
  • Funkcja zwraca długość tekstu str, lub -1 jeśli nie może wyznaczyć długości tekstu.

Napisz program, który pobierze od użytkownika dwa teksty (txt1 oraz txt2, nie więcej niż 1000 znaków każdy), a następnie w oddzielnych liniach wyświetli:

  • długość obu tekstów (najpierw pierwszy, potem drugi, oddzielone spacjami),
  • wynik zastosowania funkcji my_strcat, z parametrami txt2, txt1.
  • wynik zastosowania funkcji my_strcpy, z parametrami txt2, txt1,

Przykładowa interakcja z programem -- sukces:

Wprowadz napis pierwszy: To jest pierwszy tekst
Wprowadź napis drugi: A to drugi
22 10
A to drugiTo jest pierwszy tekst
To jest pierwszy tekst

Mój kod wygląda następująco: 

#include <stdio.h>
int my_strlen(const char* str){
    if(str==NULL){
        return -1;
    }
    int len=0;
    const char* ptr=str;
    while(*ptr!='\0'){
        len++;
        ptr++;
    }
    return len;
}
char* my_strcat(char* dest, const char* src){
    if(dest==NULL||src==NULL){
        return NULL;
    }
    char* ptr1=dest;
    const char* ptr2=src;
    while(*ptr1!='\0'){
        ptr1++;
    }
    while(*ptr2!='\0'){
        *ptr1=*ptr2;
        ptr1++;
        ptr2++;
    }
    *ptr1='\0';
    return dest;
}

char* my_strcpy(char* dest, const char* src) {
    if (dest == NULL || src == NULL) {
        return NULL;
    }

    size_t src_size = strlen(src);
    dest = (char*) realloc(dest,src_size + 1);
    char* ptr = dest;
    const char* ptr1 = src;

    while (*ptr1 != '\0') {
        *ptr = *ptr1;
        ptr++;
        ptr1++;
    }
    *ptr = '\0';
    return dest;
}

int main() {
    char txt1[1001], txt2[1001];
    printf("Podaj pierwszy tekst: ");
    scanf("%1000[^\n]", txt1);
    getchar();
    printf("Podaj drugi tekst: ");
    scanf("%1000[^\n]", txt2);
    printf("%d %d\n", my_strlen(txt1), my_strlen(txt2));
    printf("%s", my_strcat(txt2, txt1));
    my_strcpy(txt2, txt1);
    printf("\n%s", txt2);

    return 0;
}

Program działa prawidłowo, natomiast system dante nie chce przyjąć funkcji strcpy. Jeden z tesów wygląda następująco: 

char text_copy[] = "\nalledaN aytaS - .etercsid regnol on s\'tI .ygolonhcet noitamrofni yb nevird s\'taht tnemele eguh a sah ,yrtsudni yreve ni noitcnuf yreve ,yrtsudni yreve hcum ytterp oS .dezitigid si ecnanif ni gnineppah s\'taht gnihtyrevE .dezitigid si gnitekram ni gnineppah s\'taht gnihtyreve :gnitekram ta kool uoY";

            printf("#####START#####");
            char *text_copy_2 = my_strcpy(text_copy, "You look at marketing: everything that\'s happening in m");
            printf("#####END#####\n");
            test_error(strcmp(text_copy, "You look at marketing: everything that\'s happening in m") == 0, "Funkcja niepoprawnie skopiowała tekst, powinno być '%s', a jest '%s'", "You look at marketing: everything that\'s happening in m", text_copy);
            test_error(text_copy == text_copy_2, "Funkcja my_strcpy zwróciła niepoprawną wartość; powinna zwrócić wskaźnik na dest");

Domyślam się, że chodzi tu o błąd związany z pamięcią. W momencie w którym src jest dłuższe od dest. Prosiłabym o jakieś wskazówki, jestem początkująca i nie mam już pomysłu jak to rozwiązać. Byłabym bardzo wdzięczna.

2
komentarz 18 stycznia 2023 przez Oscar Nałogowiec (29,320 p.)
To realloc jest zbędne. Oryginalne funkcje nic nie allokują. Dostarczenie odpowiedniego miejsca w pamięci to odpowiedzialność tego, kto woła te funkcje.

Wpisując wynik realloc do parametru dest likwidujesz jego oryginalną wartość i kopiujesz dane do jakiejs 'nowej' pamięci zamiast do tej przekazanej przez wywołującego.
komentarz 18 stycznia 2023 przez Zuzan Początkujący (390 p.)

Poprawiłam już kod i rzeczywiście funkcja mi przeszła, dziękuję bardzo. Tylko że teraz pojawił się taki problem, że przy podaniu przez użytkownika tekst o długości 1000 znaków i wywołaniu funkcji my_strcpy zwraca ona tekst bez pierwszych 8 znaków i nie wiem do końca czym może być to spowodowane.

#include <stdio.h>
int my_strlen(const char* str){
    if(str==NULL){
        return -1;
    }
    int len=0;
    const char* ptr=str;
    while(*ptr!='\0'){
        len++;
        ptr++;
    }
    return len;
}
char* my_strcat(char* dest, const char* src){
    if(dest==NULL||src==NULL){
        return NULL;
    }
    char* ptr1=dest;
    const char* ptr2=src;
    while(*ptr1!='\0'){
        ptr1++;
    }
    while(*ptr2!='\0'){
        *ptr1=*ptr2;
        ptr1++;
        ptr2++;
    }
    *ptr1='\0';
    return dest;
}

char* my_strcpy(char* dest, const char* src) {
    if (dest == NULL || src == NULL) {
        return NULL;
    }

    char* ptr = dest;
    const char* ptr1 = src;
    while (*ptr1 != '\0') {
        *ptr = *ptr1;
        ptr++;
        ptr1++;
    }
    *ptr = '\0';
    return dest;
}

int main() {
    char txt1[1001], txt2[1001];
    printf("Podaj pierwszy tekst: ");
    scanf("%1000[^\n]", txt1);
    while(getchar()!='\n'&& getchar()!=EOF);
    printf("Podaj drugi tekst: ");
    scanf("%1000[^\n]", txt2);
    printf("%d %d\n", my_strlen(txt1), my_strlen(txt2));
    printf("%s\n", my_strcat(txt2, txt1));
    my_strcpy(txt2, txt1);
    printf("%s", txt2);

    return 0;
}

 

komentarz 18 stycznia 2023 przez Oscar Nałogowiec (29,320 p.)
Jęsli łączysz dwa stringi po ok 1000 znaków (strcat) to wynik będzie miał ok 2000 znaków.

Wychodzi poza tablicę i wynik jest nieokreślony. Sama funkcja my_strcpy nie wygląda na błędną.
komentarz 18 stycznia 2023 przez Zuzan Początkujący (390 p.)
Tylko, że funkcja strcpy zamienia jeden ciąg na drugi. Czy w takiej sytuacji mimo wszystko zwiększa się ilość znaków ?
komentarz 19 stycznia 2023 przez Oscar Nałogowiec (29,320 p.)

W podanym kodzie najpierw jest strcat (linia 56) a dopiero potem strcpy.

Jesli masz to podaj taki najprostszy kod w którym występuje dany błąd.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 1,788 wizyt
pytanie zadane 6 stycznia 2018 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
0 głosów
1 odpowiedź 643 wizyt
pytanie zadane 20 lutego 2016 w C i C++ przez Turqus Obywatel (1,420 p.)
0 głosów
3 odpowiedzi 1,622 wizyt

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...