จะใช้ Strcpy () ในภาษา C ได้อย่างไร?

How Use Strcpy C Language



ในบทความนี้ เราจะมาเรียนรู้เกี่ยวกับฟังก์ชัน strcpy() ในภาษาซี ฟังก์ชัน strcpy() เป็นฟังก์ชันไลบรารีมาตรฐานที่ได้รับความนิยมอย่างมากในการดำเนินการคัดลอกสตริงในภาษาการเขียนโปรแกรม C มีไฟล์ส่วนหัวมาตรฐานหลายไฟล์ในภาษาการเขียนโปรแกรม C เพื่อดำเนินการตามมาตรฐาน string.h เป็นหนึ่งในไฟล์ส่วนหัวดังกล่าว ซึ่งมีฟังก์ชันไลบรารีมาตรฐานหลายอย่างเพื่อดำเนินการกับสตริง ฟังก์ชัน strcpy() เป็นหนึ่งในฟังก์ชันไลบรารีที่จัดเตรียมโดย string.h

ไวยากรณ์:

char* strcpy (char*ปลายทาง_ที่ตั้ง, const char*source_string);

ทำความเข้าใจกับ strcpy():

จุดประสงค์เดียวของฟังก์ชัน strcpy() คือการคัดลอกสตริงจากต้นทางไปยังปลายทาง ตอนนี้ ให้เราดูไวยากรณ์ด้านบนของฟังก์ชัน strcpy() ฟังก์ชัน strcpy() สามารถรับพารามิเตอร์ได้สองค่า -







  • ถ่าน * ปลายทาง
  • อักขระ const * source

ซอร์สเป็นค่าคงที่ที่นี่เพื่อให้แน่ใจว่าฟังก์ชัน strcpy() ไม่สามารถเปลี่ยนสตริงต้นทางได้ ฟังก์ชัน strcpy() คัดลอกอักขระทั้งหมด (รวมถึงอักขระ NULL ที่ส่วนท้ายของสตริง) จากสตริงต้นทางไปยังปลายทาง เมื่อการคัดลอกเสร็จสมบูรณ์จากต้นทางไปยังปลายทาง ฟังก์ชัน strcpy() จะส่งคืนที่อยู่ของปลายทางกลับไปยังฟังก์ชันผู้เรียก



จุดสำคัญที่ควรสังเกตที่นี่คือ ฟังก์ชัน strcpy() ไม่ได้ต่อท้ายสตริงต้นทางกับสตริงปลายทาง มันค่อนข้างจะแทนที่เนื้อหาของปลายทางด้วยเนื้อหาของสตริงต้นทาง



นอกจากนี้ ฟังก์ชัน strcpy() จะไม่ทำการตรวจสอบใดๆ เพื่อให้แน่ใจว่าขนาดของปลายทางนั้นมากกว่าสตริงต้นทาง มันเป็นความรับผิดชอบของโปรแกรมเมอร์โดยสมบูรณ์





ตัวอย่าง:

ตอนนี้ เราจะเห็นหลายตัวอย่างเพื่อทำความเข้าใจฟังก์ชัน strcpy():

  1. strcpy() – การทำงานปกติ (example1.c)
  2. strcpy() – กรณีที่-1 (example2.c)
  3. strcpy() – กรณีที่ 2 (example3.c)
  4. strcpy() – กรณีที่-3 (example4.c)
  5. strcpy() – เวอร์ชันที่กำหนดโดยผู้ใช้ (example5.c)
  6. strcpy() - เวอร์ชันที่กำหนดโดยผู้ใช้ Optimized (example6.c)

strcpy() – การทำงานปกติ (example1.c):

โปรแกรมตัวอย่างนี้แสดงวิธีการดำเนินการคัดลอกสตริงปกติโดยใช้ฟังก์ชัน strcpy() ในภาษาการเขียนโปรแกรม C โปรดทราบว่าความยาวของสตริงปลายทางคือ 30 (อักขระปลายทาง_str[30]; ) ซึ่งมากกว่าความยาวของสตริงต้นทาง (ความยาว 18 รวมอักขระ NULL) เพื่อให้ปลายทางสามารถรองรับอักขระทั้งหมดจาก สตริงต้นทาง



#รวม
#รวม

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';
charปลายทาง_str[30];

printf ('ก่อนที่จะเรียกใช้ฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

strcpy (ปลายทาง_str,source_str);

printf ('หลังจากรันฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

กลับ 0;
}

strcpy() – กรณีที่-1 (example2.c):

จุดประสงค์ของโปรแกรมตัวอย่างนี้คือเพื่ออธิบายให้ชัดเจนว่าเกิดอะไรขึ้นเมื่อความยาวของสตริงปลายทางน้อยกว่าความยาวของสตริงต้นทาง ในกรณีดังกล่าว ตำแหน่งปลายทางจะมีช่องว่าง/ไบต์ไม่เพียงพอเพื่อรองรับอักขระทั้งหมด (รวมถึงอักขระ NULL) จากสตริงต้นทาง สองสิ่งที่คุณควรจำไว้เสมอ:

  1. ฟังก์ชัน strcpy() จะไม่ตรวจสอบว่าปลายทางมีพื้นที่เพียงพอหรือไม่
  2. นี่อาจเป็นอันตรายในซอฟต์แวร์ฝังตัวเนื่องจาก strcpy() จะแทนที่พื้นที่หน่วยความจำที่อยู่นอกขอบเขตของปลายทาง

มาดูตัวอย่างโปรแกรมกัน เราได้ประกาศ source_str และเริ่มต้นเป็น www.linuxhint.com ซึ่งจะใช้หน่วยความจำ 18 ไบต์ในการจัดเก็บ รวมถึงอักขระ Null ที่ส่วนท้ายของสตริง จากนั้น เราได้ประกาศอาร์เรย์อักขระอื่น เช่น destination_str ที่มีขนาดเพียง 5 ดังนั้น destination_str ไม่สามารถเก็บสตริงต้นทางที่มีขนาดรวม 18 ไบต์ได้

แต่ถึงกระนั้น เรากำลังเรียกใช้ฟังก์ชัน strcpy() เพื่อคัดลอกสตริงต้นทางไปยังสตริงปลายทาง จากผลลัพธ์ด้านล่าง เราจะเห็นว่า strcpy() ไม่บ่นเลย ในกรณีนี้ ฟังก์ชัน strcpy() จะเริ่มคัดลอกอักขระจากสตริงต้นทาง (จนกว่าจะพบอักขระ NULL ในสตริงต้นทาง) ไปยังที่อยู่ปลายทาง (แม้ว่าขอบเขตปลายทางจะเกิน) นั่นหมายความว่าฟังก์ชัน strcpy() ไม่ได้ทำการตรวจสอบขอบเขตสำหรับอาร์เรย์ปลายทาง ในที่สุด ฟังก์ชัน strcpy() จะเขียนทับที่อยู่หน่วยความจำที่ไม่ได้จัดสรรให้กับอาร์เรย์ปลายทาง นี่คือเหตุผลที่ฟังก์ชัน strcpy() จะลงเอยด้วยการเขียนทับตำแหน่งหน่วยความจำที่อาจจัดสรรให้กับตัวแปรอื่น

ในตัวอย่างนี้ เราจะเห็นได้จากผลลัพธ์ด้านล่าง ว่าฟังก์ชัน strcpy() จะเขียนทับสตริงต้นทางเอง โปรแกรมเมอร์ควรระมัดระวังกับพฤติกรรมดังกล่าวเสมอ

#รวม
#รวม

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';
charปลายทาง_str[5];

printf ('ก่อนที่จะเรียกใช้ฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

strcpy (ปลายทาง_str,source_str);

printf ('หลังจากรันฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

//printf('ที่อยู่แหล่งที่มา = %u (0x%x) ', &source_str[0], &source_str[0]);
//printf('ที่อยู่ปลายทาง = %u (0x%x) ', &destination_str[0], &destination_str[0]);

กลับ 0;
}

strcpy() – กรณีที่ 2 (example3.c):

โปรแกรมนี้แสดงสถานการณ์เมื่อขนาดสตริงปลายทางมากกว่าขนาดสตริงต้นทางและสตริงปลายทางถูกเตรียมใช้งานด้วยค่าบางอย่างแล้ว ในตัวอย่างนี้ เราได้เริ่มต้น:

  • source_str ถึง www.linuxhint.com [ขนาด = 17+1 = 18]
  • ปลายทาง_str ถึง I_AM_A_DESTINATION_STRING [ขนาด = 25+1 = 26]

ฟังก์ชัน strcpy() จะคัดลอกอักขระทั้งหมด 17 ตัวและอักขระ NULL จากสตริงต้นทางไปยังสตริงปลายทาง แต่จะไม่แทนที่/เปลี่ยนไบต์ที่เหลือ (ไบต์ 19 เป็น 26 หนึ่งไบต์ตาม) ในอาร์เรย์ปลายทาง เราใช้ for loop เพื่อวนซ้ำบนอาร์เรย์ปลายทางและพิมพ์อาร์เรย์ทั้งหมดเพื่อพิสูจน์ว่าไบต์-19 ถึง 26 ไม่เปลี่ยนแปลงในอาร์เรย์ปลายทาง นั่นคือเหตุผลที่เราเห็นผลลัพธ์สุดท้ายเป็น:

www.linuxhint.com_STRING .

#รวม
#รวม


/* โปรแกรมนี้แสดงสถานการณ์เมื่อ:

ขนาดสตริงปลายทาง > ขนาดสตริงต้นทาง

และเรารันฟังก์ชัน strcpy() เพื่อคัดลอก
สตริงต้นทางไปยังปลายทาง

หมายเหตุ: ขนาดสตริงปลายทางควรเสมอ
มากกว่าหรือเท่ากับสตริงต้นทาง
* /

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';
charปลายทาง_str[26] = 'I_AM_A_DESTINATION_STRING';

printf ('ก่อนที่จะเรียกใช้ฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

strcpy (ปลายทาง_str,source_str);

printf ('หลังจากรันฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);


/* พิมพ์สตริงปลายทางโดยใช้ for loop*/
printf ('พิมพ์อักขระสตริงปลายทางโดย char :NSNS');
printf ('NSสตริงปลายทาง = ');

สำหรับ(intผม=0;ผม<25;ผม++)
{
printf ('% ค',ปลายทาง_str[ผม]);
}
printf ('NSNS');

กลับ 0;
}

strcpy() – กรณีที่-3 (example4.c):

เราได้พิจารณาโปรแกรมนี้เป็นตัวอย่างเพื่อแสดงให้เห็นว่าเราไม่ควรเรียก strcpy() ด้วยสตริงตามตัวอักษรเป็นปลายทาง ซึ่งจะทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดไว้ และในที่สุด โปรแกรมก็จะหยุดทำงาน

#รวม
#รวม

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';

printf ('ก่อนที่จะเรียกใช้ฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);

/* ห้ามเรียก strcpy() โดยใช้สตริงตามตัวอักษรเป็นปลายทาง
โปรแกรมจะพัง
* /

strcpy ('destination_str',source_str);

printf ('หลังจากรันฟังก์ชัน strcpy() :NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);

กลับ 0;
}

strcpy() – เวอร์ชันที่กำหนดโดยผู้ใช้ (example5.c):

ในโปรแกรมตัวอย่างนี้ เราได้แสดงวิธีเขียนฟังก์ชัน strcpy() เวอร์ชันที่ผู้ใช้กำหนด

#รวม
char *strcpy_user_defined(char *ปลายทาง, const char *src);

/* ฟังก์ชัน strcpy() เวอร์ชันที่ผู้ใช้กำหนด */
char *strcpy_user_defined(char *ปลายทาง, const char *src)
{
char *dest_backup=ปลายทาง;

ในขณะที่(*src! = ' 0') /* วนซ้ำจนกว่าจะพบ ''*/
{
*ปลายทาง= *src; /* คัดลอกถ่านต้นทางไปยังปลายทาง */
src++; /* เพิ่มตัวชี้แหล่งที่มา */
ปลายทาง++; /* เพิ่มตัวชี้ปลายทาง */
}

*ปลายทาง= ' 0'; /* ใส่ '' ที่ปลายทางอย่างชัดเจน*/

กลับdest_backup;
}

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';
charปลายทาง_str[30];

printf ('ก่อนที่จะเรียกใช้ฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด:NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

/* เรียกฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด */
strcpy_user_defined(ปลายทาง_str,source_str);

printf ('หลังจากรันฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด:NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

กลับ 0;
}

strcpy() - เวอร์ชันที่กำหนดโดยผู้ใช้ Optimized (example6.c):

ในโปรแกรมตัวอย่างนี้ เราจะเพิ่มประสิทธิภาพเวอร์ชันที่ผู้ใช้กำหนดของ strcpy()

#รวม
char *strcpy_user_defined(char *ปลายทาง, const char *src);


/* ฟังก์ชัน strcpy() ที่ผู้ใช้กำหนดเวอร์ชันที่ปรับให้เหมาะสม */
char *strcpy_user_defined(char *ปลายทาง, const char *src)
{
char *dest_backup=ปลายทาง;

ในขณะที่(*ปลายทาง++ = *src++)
;

กลับdest_backup;
}

intหลัก()
{
charsource_str[] = 'www.linuxhint.com';
charปลายทาง_str[30];

printf ('ก่อนที่จะเรียกใช้ฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด:NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

/* เรียกฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด */
strcpy_user_defined(ปลายทาง_str,source_str);

printf ('หลังจากรันฟังก์ชันคัดลอกสตริงที่ผู้ใช้กำหนด:NSNS');
printf ('NSสตริงต้นทาง = %sNS',source_str);
printf ('NSสตริงปลายทาง = %sNSNS',ปลายทาง_str);

กลับ 0;
}

บทสรุป :

ฟังก์ชัน strcpy() เป็นฟังก์ชันไลบรารีที่ได้รับความนิยมและมีประโยชน์มากในการคัดลอกสตริงในภาษาการเขียนโปรแกรม C ส่วนใหญ่จะใช้เพื่อคัดลอกสตริงจากตำแหน่งหนึ่งไปยังอีกตำแหน่งหนึ่ง อย่างไรก็ตาม เราต้องการย้ำข้อเท็จจริงที่ว่าฟังก์ชัน strcpy() ไม่ได้ทำการตรวจสอบขอบเขตสำหรับอาร์เรย์ปลายทาง ซึ่งอาจนำไปสู่ข้อบกพร่องของซอฟต์แวร์ที่ร้ายแรงหากละเลย เป็นความรับผิดชอบของโปรแกรมเมอร์เสมอที่จะต้องตรวจสอบให้แน่ใจว่าอาร์เรย์ปลายทางมีพื้นที่เพียงพอสำหรับเก็บอักขระทั้งหมดจากสตริงต้นทางรวมถึงอักขระ NULL