Jak używać Strcpy() w języku C?

How Use Strcpy C Language



W tym artykule poznamy funkcję strcpy() w języku programowania C. Funkcja strcpy() jest bardzo popularną funkcją biblioteki standardowej do wykonywania operacji kopiowania ciągów w języku programowania C. Istnieje kilka standardowych plików nagłówkowych w języku programowania C do wykonywania standardowych operacji. Jednym z takich plików nagłówkowych jest string.h, który udostępnia kilka standardowych funkcji bibliotecznych do wykonywania operacji na łańcuchach. Funkcja strcpy() jest jedną z funkcji bibliotecznych dostarczanych przez string.h.

Składnia:

zwęglać* strcpy (zwęglać*lokalizacja_docelowa, stały zwęglać*ciąg_źródłowy);

Zrozumienie strcpy():

Jedynym celem funkcji strcpy() jest skopiowanie ciągu znaków ze źródła do miejsca docelowego. Teraz spójrzmy na powyższą składnię funkcji strcpy(). Funkcja strcpy() może przyjmować dwa parametry –







  • znak * cel podróży
  • const char * źródło

Źródło jest tutaj stałą, aby zapewnić, że funkcja strcpy() nie może zmienić ciągu źródłowego. Funkcja strcpy() kopiuje wszystkie znaki (w tym znak NULL na końcu ciągu) z ciągu źródłowego do miejsca docelowego. Po zakończeniu operacji kopiowania ze źródła do miejsca docelowego funkcja strcpy() zwraca adres miejsca docelowego z powrotem do funkcji wywołującej.



Ważnym punktem, na który należy zwrócić uwagę, jest to, że funkcja strcpy() nie dołącza ciągu źródłowego do ciągu docelowego. Zamiast tego zastępuje zawartość miejsca docelowego zawartością ciągu źródłowego.



Ponadto funkcja strcpy() nie wykonuje żadnych kontroli, aby upewnić się, że rozmiar miejsca docelowego jest większy niż łańcuch źródłowy, za to całkowicie odpowiada programista.





Przykłady:

Teraz zobaczymy kilka przykładów, aby zrozumieć funkcję strcpy():

  1. strcpy() — normalne działanie (przykład1.c)
  2. strcpy() — Przypadek-1 (przykład2.c)
  3. strcpy() — przypadek 2 (przykład3.c)
  4. strcpy() – Przypadek-3 (przykład4.c)
  5. strcpy() — wersja zdefiniowana przez użytkownika (przykład5.c)
  6. strcpy() — zoptymalizowana wersja zdefiniowana przez użytkownika (przykład6.c)

strcpy() — normalne działanie (przykład1.c):

Ten przykładowy program pokazuje, jak wykonać normalną operację kopiowania ciągów za pomocą funkcji strcpy() w języku programowania C. Należy pamiętać, że długość ciągu docelowego wynosi 30 (char destination_str[30]; ), co jest większe niż długość ciągu źródłowego (długość wynosi 18, w tym znak NULL), aby miejsce docelowe mogło pomieścić wszystkie znaki z ciągu ciąg źródłowy.



#włączać
#włączać

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;
zwęglaćdestination_str[30];

printf ('Przed wywołaniem funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

strcpy (destination_str,source_str);

printf ('Po wykonaniu funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

powrót 0;
}

strcpy() – Przypadek-1 (przykład2.c):

Intencją tego przykładowego programu jest jasne wyjaśnienie, co się dzieje, gdy długość ciągu docelowego jest mniejsza niż długość ciągu źródłowego. W takich przypadkach lokalizacja docelowa nie będzie miała wystarczającej ilości spacji/bajtów, aby pomieścić wszystkie znaki (w tym znak NULL) z ciągu źródłowego. Dwie rzeczy, o których zawsze powinieneś pamiętać:

  1. Funkcja strcpy() nie sprawdzi, czy miejsce docelowe ma wystarczającą ilość miejsca.
  2. Może to być niebezpieczne w oprogramowaniu wbudowanym, ponieważ strcpy() zastąpi obszar pamięci poza granicami miejsca docelowego.

Spójrzmy na przykładowy program. Zadeklarowaliśmy source_str i zainicjalizowaliśmy go do www.linuxhint.pl , który zajmie 18 bajtów w pamięci do przechowywania, w tym znak Null na końcu ciągu. Następnie zadeklarowaliśmy kolejną tablicę znaków, tj. destination_str o rozmiarze zaledwie 5. Tak więc destination_str nie może pomieścić łańcucha źródłowego o łącznym rozmiarze 18 bajtów.

Ale nadal wywołujemy funkcję strcpy(), aby skopiować ciąg źródłowy do ciągu docelowego. Z poniższych danych wyjściowych widać, że strcpy() w ogóle nie narzekała. W takim przypadku funkcja strcpy() rozpocznie kopiowanie znaku z ciągu źródłowego (do momentu znalezienia znaku NULL w ciągu źródłowym) do adresu docelowego (nawet jeśli granica docelowa przekracza). Oznacza to, że funkcja strcpy() nie sprawdza granic dla tablicy docelowej. Ostatecznie funkcja strcpy() nadpisze adresy pamięci, które nie są przydzielone do tablicy docelowej. To dlatego funkcja strcpy() skończy się nadpisywaniem lokalizacji pamięci, które mogą być przydzielone innej zmiennej.

W tym przykładzie widzimy z poniższych danych wyjściowych, że funkcja strcpy() nadpisuje sam ciąg źródłowy. Programiści powinni zawsze być ostrożni z takim zachowaniem.

#włączać
#włączać

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;
zwęglaćdestination_str[5];

printf ('Przed wywołaniem funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

strcpy (destination_str,source_str);

printf ('Po wykonaniu funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

//printf('Adres źródłowy = %u (0x%x) ', &source_str[0], &source_str[0]);
//printf('Adres docelowy = %u (0x%x) ', &destination_str[0], &destination_str[0]);

powrót 0;
}

strcpy() – Przypadek-2 (przykład3.c):

Ten program ilustruje sytuację, w której rozmiar ciągu docelowego jest większy niż rozmiar ciągu źródłowego, a ciąg docelowy jest już zainicjowany z pewną wartością. W tym przykładzie zainicjowaliśmy:

  • source_str to www.linuxhint.pl [rozmiar = 17+1 = 18]
  • destination_str do I_AM_A_DESTINATION_STRING [rozmiar = 25+1 = 26]

Funkcja strcpy() skopiuje wszystkie 17 znaków i znak NULL z ciągu źródłowego do ciągu docelowego. Ale nie zastąpi/zmieni pozostałych bajtów (Bajt 19 na 26, oparty na jednym) w tablicy docelowej. Wykorzystaliśmy pętlę for do iteracji po tablicy docelowej i wypisania całej tablicy, aby udowodnić, że bajty od 19 do 26 są niezmienione w tablicy docelowej. Dlatego widzimy ostatnie wyjście jako:

www.linuxhint.com_STRING .

#włączać
#włączać


/* Ten program ilustruje sytuację, gdy :

docelowy rozmiar ciągu > źródłowy rozmiar ciągu

i wykonujemy funkcję strcpy(), aby skopiować
ciąg źródłowy do miejsca docelowego.

Uwaga: docelowy rozmiar ciągu powinien zawsze
być większa lub równa ciągowi źródłowemu.
* /

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;
zwęglaćdestination_str[26] = „I_AM_A_DESTINATION_STRING”;

printf ('Przed wywołaniem funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

strcpy (destination_str,source_str);

printf ('Po wykonaniu funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);


/* wypisz docelowy ciąg znaków za pomocą pętli for*/
printf ('Wydrukuj łańcuch docelowy char by char : ');
printf ('TCiąg docelowy = ');

dla(inti=0;i<25;i++)
{
printf ('% C',destination_str[i]);
}
printf (' ');

powrót 0;
}

strcpy() – Przypadek-3 (przykład4.c):

Rozważaliśmy ten program jako przykład pokazujący, że nigdy nie powinniśmy wywoływać strcpy() z literałem ciągu jako miejscem docelowym. Spowoduje to niezdefiniowane zachowanie iw końcu program ulegnie awarii.

#włączać
#włączać

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;

printf ('Przed wywołaniem funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);

/* Nigdy nie wywołuj strcpy() z literałem ciągu jako miejscem docelowym.
Program ulegnie awarii.
* /

strcpy ('destination_str',source_str);

printf ('Po wykonaniu funkcji strcpy() : ');
printf ('TCiąg źródłowy = %s ',source_str);

powrót 0;
}

strcpy() — wersja zdefiniowana przez użytkownika (przykład5.c):

W tym przykładowym programie pokazaliśmy, jak napisać zdefiniowaną przez użytkownika wersję funkcji strcpy().

#włączać
zwęglać *strcpy_user_defined(zwęglać *przeznaczenie, stały zwęglać *src);

/* Zdefiniowana przez użytkownika wersja funkcji strcpy() */
zwęglać *strcpy_user_defined(zwęglać *przeznaczenie, stały zwęglać *src)
{
zwęglać *dest_backup=przeznaczenie;

podczas(*src! = ' 0') /* Iteruj aż do znalezienia ''.*/
{
*przeznaczenie= *src; /* Skopiuj znak źródłowy do miejsca docelowego */
src++; /* Zwiększ wskaźnik źródła */
przeznaczenie++; /* Zwiększ wskaźnik celu */
}

*przeznaczenie= ' 0'; /* Wstaw jawnie '' w miejscu docelowym*/

powrótdest_backup;
}

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;
zwęglaćdestination_str[30];

printf ('Przed wywołaniem funkcji kopiowania ciągu znaków zdefiniowanego przez użytkownika: ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

/* Wywołanie funkcji kopiowania napisów zdefiniowanej przez użytkownika */
strcpy_user_defined(destination_str,source_str);

printf ('Po wykonaniu funkcji kopiowania ciągu zdefiniowanego przez użytkownika: ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

powrót 0;
}

strcpy() — zoptymalizowana wersja zdefiniowana przez użytkownika (przykład6.c):

Teraz, w tym przykładowym programie, zamierzamy zoptymalizować zdefiniowaną przez użytkownika wersję strcpy().

#włączać
zwęglać *strcpy_user_defined(zwęglać *przeznaczenie, stały zwęglać *src);


/* Zoptymalizowana wersja funkcji strcpy() zdefiniowanej przez użytkownika */
zwęglać *strcpy_user_defined(zwęglać *przeznaczenie, stały zwęglać *src)
{
zwęglać *dest_backup=przeznaczenie;

podczas(*przeznaczenie++ = *src++)
;

powrótdest_backup;
}

intGłówny()
{
zwęglaćsource_str[] = „www.linuxhint.com”;
zwęglaćdestination_str[30];

printf ('Przed wywołaniem funkcji kopiowania ciągu znaków zdefiniowanego przez użytkownika: ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

/* Wywołanie funkcji kopiowania napisów zdefiniowanej przez użytkownika */
strcpy_user_defined(destination_str,source_str);

printf ('Po wykonaniu funkcji kopiowania ciągu zdefiniowanego przez użytkownika: ');
printf ('TCiąg źródłowy = %s ',source_str);
printf ('TCiąg docelowy = %s ',destination_str);

powrót 0;
}

Wniosek :

Funkcja strcpy() jest bardzo popularną i poręczną funkcją biblioteczną do wykonywania operacji kopiowania ciągów znaków w języku programowania C. Jest to używane głównie do kopiowania ciągu z jednej lokalizacji do drugiej. Chcemy jednak powtórzyć fakt, że funkcja strcpy() nie sprawdza granic dla tablicy docelowej, co może prowadzić do poważnego błędu oprogramowania, jeśli zostanie zignorowane. Zawsze obowiązkiem programisty jest upewnienie się, że tablica docelowa ma wystarczająco dużo miejsca, aby pomieścić wszystkie znaki z łańcucha źródłowego, w tym znak NULL.