C dilinde Strcpy() nasıl kullanılır?

How Use Strcpy C Language



Bu yazımızda C programlama dilindeki strcpy() fonksiyonunu öğreneceğiz. strcpy() işlevi, C programlama dilinde dize kopyalama işlemini gerçekleştirmek için çok popüler bir standart kitaplık işlevidir. Standart işlemleri gerçekleştirmek için C programlama dilinde birkaç standart başlık dosyası vardır. string.h, string işlemlerini gerçekleştirmek için birkaç standart kitaplık işlevi sağlayan bu tür başlık dosyalarından biridir. strcpy() işlevi, string.h tarafından sağlanan kitaplık işlevlerinden biridir.

Sözdizimi:

karakter* strcpy (karakter*varış yeri, const karakter*kaynak_dizesi);

strcpy()'yi anlamak:

strcpy() işlevinin tek amacı, bir dizeyi kaynaktan hedefe kopyalamaktır. Şimdi strcpy() fonksiyonunun yukarıdaki sözdizimine bakalım. strcpy() işlevi iki parametreyi kabul edebilir –







  • karakter * hedef
  • const karakter * kaynak

strcpy() işlevinin kaynak dizeyi değiştirememesi için kaynak burada bir sabittir. strcpy() işlevi, tüm karakterleri (dizenin sonundaki NULL karakteri dahil) kaynak dizeden hedefe kopyalar. Kaynaktan hedefe kopyalama işlemi tamamlandıktan sonra, strcpy() işlevi, hedefin adresini arayan işlevine geri döndürür.



Burada dikkat edilmesi gereken önemli nokta, strcpy() fonksiyonunun kaynak dizgiyi hedef dizgeye eklememesidir. Bunun yerine hedefin içeriğini kaynak dizenin içeriğiyle değiştirir.



Ayrıca, strcpy() işlevi, hedefin boyutunun kaynak dizeden daha fazla olduğundan emin olmak için herhangi bir kontrol yapmaz, tamamen programcının sorumluluğundadır.





Örnekler:

Şimdi strcpy() fonksiyonunu anlamak için birkaç örnek göreceğiz:

  1. strcpy() – Normal Çalışma (örnek1.c)
  2. strcpy() – Durum-1 (örnek2.c)
  3. strcpy() – Durum-2 (örnek3.c)
  4. strcpy() – Durum-3 (example4.c)
  5. strcpy() – Kullanıcı Tanımlı Sürüm (example5.c)
  6. strcpy() – Kullanıcı Tanımlı Sürüm Optimize Edildi (example6.c)

strcpy() – Normal İşlem (örnek1.c):

Bu örnek program, C programlama dilinde strcpy() işlevini kullanarak normal bir dize kopyalama işleminin nasıl gerçekleştirileceğini gösterir. Lütfen hedef dizenin uzunluğunun kaynak dizenin uzunluğundan (boş karakter dahil uzunluk 18'dir) daha büyük olan 30 (char target_str[30]; ) olduğuna dikkat edin, böylece hedef, hedef dizedeki tüm karakterleri barındırabilir. kaynak dizesi.



#Dahil etmek
#Dahil etmek

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';
karakterhedef_str[30];

baskı ('strcpy() işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

strcpy (hedef_str,kaynak_str);

baskı ('strcpy() işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

dönüş 0;
}

strcpy() – Durum-1 (örnek2.c):

Bu örnek programın amacı, hedef dizgenin uzunluğu kaynak dizgenin uzunluğundan daha az olduğunda ne olduğunu açıkça açıklamaktır. Bu gibi durumlarda, hedef konum, kaynak dizedeki tüm karakterleri (BOŞ karakter dahil) barındırmak için yeterli boşluğa/bayta sahip olmayacaktır. Her zaman aklınızda bulundurmanız gereken iki şey:

  1. strcpy() işlevi, hedefin yeterli alana sahip olup olmadığını kontrol etmeyecektir.
  2. Bu, gömülü yazılımda tehlikeli olabilir, çünkü strcpy() hedefin sınırlarının ötesindeki bellek alanını değiştirecektir.

Örnek programa bakalım. source_str'yi bildirdik ve onu başlattık www.linuxhint.com dizenin sonundaki Null karakteri de dahil olmak üzere, bellekte saklanması 18 bayt sürecektir. Daha sonra başka bir karakter dizisi tanımladık, yani sadece 5 boyutunda target_str. Bu nedenle, target_str toplam boyutu 18 bayt olan kaynak dizeyi tutamaz.

Ama yine de, kaynak dizgiyi hedef dizgeye kopyalamak için strcpy() işlevini çağırıyoruz. Aşağıdaki çıktıdan, strcpy() öğesinin hiç şikayet etmediğini görebiliriz. Bu durumda, strcpy() işlevi, karakteri kaynak dizeden (kaynak dizede NULL karakteri bulana kadar) hedef adrese (hedef sınırı aşsa bile) kopyalamaya başlayacaktır. Bu, strcpy() işlevinin hedef dizi için herhangi bir sınır denetimi yapmadığı anlamına gelir. Sonunda, strcpy() işlevi, hedef diziye atanmamış bellek adreslerinin üzerine yazacaktır. Bu nedenle strcpy() işlevi, farklı bir değişkene tahsis edilmiş olabilecek bellek konumlarının üzerine yazacaktır.

Bu örnekte, aşağıdaki çıktıdan strcpy() fonksiyonunun kaynak dizginin üzerine yazdığını görebiliriz. Programcılar bu tür davranışlara karşı her zaman dikkatli olmalıdır.

#Dahil etmek
#Dahil etmek

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';
karakterhedef_str[5];

baskı ('strcpy() işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

strcpy (hedef_str,kaynak_str);

baskı ('strcpy() işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

//printf('Kaynak Adresi = %u (0x%x) ', &source_str[0], &source_str[0]);
//printf('Hedef Adres = %u (0x%x) ', &destination_str[0], &destination_str[0]);

dönüş 0;
}

strcpy() – Durum-2 (örnek3.c):

Bu program, hedef dize boyutunun kaynak dize boyutundan büyük olduğu ve hedef dizenin zaten bir değerle başlatıldığı durumu gösterir. Bu örnekte, şunu başlattık:

  • kaynak_str için www.linuxhint.com [beden = 17+1 = 18]
  • target_str - I_AM_A_DESTINATION_STRING [boyut = 25+1 = 26]

strcpy() işlevi, 17 karakterin tümünü ve NULL karakterini kaynak dizeden hedef dizeye kopyalayacaktır. Ancak, hedef dizideki kalan baytları (Byte 19 - 26, bir tabanlı) değiştirmez/değiştirmez. Hedef dizi üzerinde yineleme yapmak için for döngüsünü kullandık ve hedef dizide 19 ile 26 arasındaki baytların değişmediğini kanıtlamak için tüm diziyi yazdırdık. Bu yüzden son çıktıyı şu şekilde görüyoruz:

www.linuxhint.com_STRING .

#Dahil etmek
#Dahil etmek


/* Bu program şu durumlarda durumu gösterir:

hedef dize boyutu > kaynak dize boyutu

ve kopyalamak için strcpy() işlevini yürütürüz.
hedefe kaynak dizesi.

Not: Hedef dize boyutu her zaman
kaynak dizeden büyük veya ona eşit olabilir.
* /

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';
karakterhedef_str[26] = 'I_AM_A_DESTINATION_STRING';

baskı ('strcpy() işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

strcpy (hedef_str,kaynak_str);

baskı ('strcpy() işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);


/* for döngüsü kullanarak hedef dizgeyi yazdır*/
baskı ('Hedef dizgeyi char ile yazdırın: ');
baskı ('THedef Dize = ');

için(intben=0;ben<25;ben++)
{
baskı ('% C',hedef_str[ben]);
}
baskı (' ');

dönüş 0;
}

strcpy() – Durum-3 (örnek4.c):

Bu programı, hedef olarak bir dize değişmezi ile asla strcpy() çağırmamamız gerektiğini göstermek için bir örnek olarak düşündük. Bu tanımsız davranışa neden olur ve sonunda program çöker.

#Dahil etmek
#Dahil etmek

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';

baskı ('strcpy() işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);

/* Hedef olarak dizge değişmezi ile asla strcpy() çağırma.
Program çökecek.
* /

strcpy ('destination_str',kaynak_str);

baskı ('strcpy() işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);

dönüş 0;
}

strcpy() – Kullanıcı Tanımlı Sürüm (example5.c):

Bu örnek programda, strcpy() fonksiyonunun kullanıcı tanımlı bir versiyonunun nasıl yazılacağını gösterdik.

#Dahil etmek
karakter *strcpy_user_defined(karakter *hedef, const karakter *kaynak);

/* strcpy() fonksiyonunun kullanıcı tanımlı versiyonu */
karakter *strcpy_user_defined(karakter *hedef, const karakter *kaynak)
{
karakter *dest_backup=hedef;

süre(*kaynak! = ' 0') /* '' bulunana kadar yinelenir.*/
{
*hedef= *kaynak; /* Kaynak karakteri hedefe kopyala */
kaynak++; /* Kaynak işaretçisini artır */
hedef++; /* Hedef işaretçiyi artır */
}

*hedef= ' 0'; /* Hedefe açıkça '' ekleyin*/

dönüşdest_backup;
}

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';
karakterhedef_str[30];

baskı ('Kullanıcı tanımlı dize kopyalama işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

/* Kullanıcı tanımlı string kopyalama fonksiyonunu çağırıyor */
strcpy_user_defined(hedef_str,kaynak_str);

baskı ('Kullanıcı tanımlı dize kopyalama işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

dönüş 0;
}

strcpy() – Kullanıcı Tanımlı Sürüm Optimize Edildi (example6.c):

Şimdi, bu örnek programda, strcpy()'nin kullanıcı tanımlı sürümünü optimize edeceğiz.

#Dahil etmek
karakter *strcpy_user_defined(karakter *hedef, const karakter *kaynak);


/* Kullanıcı tanımlı strcpy() fonksiyonunun optimize edilmiş versiyonu */
karakter *strcpy_user_defined(karakter *hedef, const karakter *kaynak)
{
karakter *dest_backup=hedef;

süre(*hedef++ = *kaynak++)
;

dönüşdest_backup;
}

intana()
{
karakterkaynak_str[] = 'www.linuxhint.com';
karakterhedef_str[30];

baskı ('Kullanıcı tanımlı dize kopyalama işlevini çağırmadan önce: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

/* Kullanıcı tanımlı string kopyalama fonksiyonunu çağırıyor */
strcpy_user_defined(hedef_str,kaynak_str);

baskı ('Kullanıcı tanımlı dize kopyalama işlevini yürüttükten sonra: ');
baskı ('TKaynak Dizisi = %s ',kaynak_str);
baskı ('THedef Dize = %s ',hedef_str);

dönüş 0;
}

Çözüm :

strcpy() işlevi, C programlama dilinde dize kopyalama işlemini gerçekleştirmek için çok popüler ve kullanışlı bir kitaplık işlevidir. Bu, esas olarak dizeyi bir konumdan başka bir konuma kopyalamak için kullanılır. Ancak, strcpy() işlevinin hedef dizi için sınır denetimi yapmadığını ve bunun göz ardı edildiğinde ciddi bir yazılım hatasına yol açabileceğini tekrarlamak istiyoruz. Hedef dizinin NULL karakteri de dahil olmak üzere kaynak dizgedeki tüm karakterleri tutacak yeterli alana sahip olduğundan emin olmak her zaman programcının sorumluluğundadır.