Làm thế nào để sử dụng Strcpy () trong ngôn ngữ C?

How Use Strcpy C Language



Trong bài này, chúng ta sẽ tìm hiểu về hàm strcpy () trong ngôn ngữ lập trình C. Hàm strcpy () là một hàm thư viện chuẩn rất phổ biến để thực hiện thao tác sao chép chuỗi trong ngôn ngữ lập trình C. Có một số tệp tiêu đề tiêu chuẩn trong ngôn ngữ lập trình C để thực hiện các hoạt động tiêu chuẩn. String.h là một trong những tệp tiêu đề như vậy, tệp này cung cấp một số hàm thư viện tiêu chuẩn để thực hiện các hoạt động chuỗi. Hàm strcpy () là một trong những hàm thư viện được cung cấp bởi string.h.

Cú pháp:

char* strcpy (char*Vị trí đích, hăng sô char*source_string);

Hiểu strcpy ():

Mục đích duy nhất của hàm strcpy () là sao chép một chuỗi từ nguồn đến đích. Bây giờ, chúng ta hãy xem cú pháp trên của hàm strcpy (). Hàm strcpy () có thể chấp nhận hai tham số:







  • char * đích
  • nguồn const char *

Nguồn là một hằng số ở đây để đảm bảo rằng hàm strcpy () không thể thay đổi chuỗi nguồn. Hàm strcpy () sao chép tất cả các ký tự (bao gồm cả ký tự NULL ở cuối chuỗi) từ chuỗi nguồn đến đích. Khi hoạt động sao chép hoàn tất từ ​​nguồn đến đích, hàm strcpy () trả về địa chỉ của đích trở lại hàm người gọi.



Điểm quan trọng cần lưu ý ở đây là, hàm strcpy () không nối chuỗi nguồn với chuỗi đích. Nó thay thế nội dung của đích bằng nội dung của chuỗi nguồn.



Ngoài ra, hàm strcpy () không thực hiện bất kỳ kiểm tra nào để đảm bảo rằng kích thước của đích nhiều hơn chuỗi nguồn, nó hoàn toàn thuộc trách nhiệm của người lập trình.





Ví dụ:

Bây giờ, chúng ta sẽ xem một số ví dụ để hiểu hàm strcpy ():

  1. strcpy () - Hoạt động bình thường (example1.c)
  2. strcpy () - Trường hợp-1 (example2.c)
  3. strcpy () - Case-2 (example3.c)
  4. strcpy () - Case-3 (example4.c)
  5. strcpy () - Phiên bản do người dùng xác định (example5.c)
  6. strcpy () - Tối ưu hóa phiên bản do người dùng xác định (example6.c)

strcpy () - Hoạt động bình thường (example1.c):

Chương trình ví dụ này cho thấy cách thực hiện thao tác sao chép chuỗi thông thường bằng cách sử dụng hàm strcpy () trong ngôn ngữ lập trình C. Xin lưu ý rằng độ dài của chuỗi đích là 30 (char đích_str [30];), lớn hơn độ dài của chuỗi nguồn (độ dài là 18 bao gồm cả ký tự NULL) để đích có thể chứa tất cả các ký tự từ chuỗi nguồn.



#bao gồm
#bao gồm

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';
charđích_str[30];

printf ('Trước khi gọi hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

strcpy (đích_str,source_str);

printf ('Sau khi thực hiện hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

trở lại 0;
}

strcpy () - Trường hợp-1 (example2.c):

Mục đích của chương trình ví dụ này là giải thích rõ ràng điều gì sẽ xảy ra khi độ dài của chuỗi đích nhỏ hơn độ dài của chuỗi nguồn. Trong những trường hợp như vậy, vị trí đích sẽ không có đủ khoảng trắng / byte để chứa tất cả các ký tự (bao gồm cả ký tự NULL) từ chuỗi nguồn. Hai điều, bạn nên luôn ghi nhớ:

  1. Hàm strcpy () sẽ không kiểm tra xem đích có đủ dung lượng hay không.
  2. Điều này có thể nguy hiểm trong phần mềm nhúng vì strcpy () sẽ thay thế vùng bộ nhớ bên ngoài ranh giới của điểm đến.

Chúng ta hãy xem chương trình ví dụ. Chúng tôi đã khai báo source_str và khởi tạo nó thành www.linuxhint.com , sẽ chiếm 18 byte trong bộ nhớ để lưu trữ, bao gồm cả ký tự Null ở cuối chuỗi. Sau đó, chúng ta đã khai báo một mảng ký tự khác, tức là destination_str với kích thước chỉ là 5. Vì vậy, target_str không thể chứa chuỗi nguồn có tổng kích thước là 18 byte.

Tuy nhiên, chúng ta vẫn đang gọi hàm strcpy () để sao chép chuỗi nguồn sang chuỗi đích. Từ đầu ra bên dưới, chúng ta có thể thấy strcpy () không phàn nàn gì cả. Trong trường hợp này, hàm strcpy () sẽ bắt đầu sao chép ký tự từ chuỗi nguồn (cho đến khi nó tìm thấy ký tự NULL trong chuỗi nguồn) đến địa chỉ đích (mặc dù vượt quá ranh giới đích). Điều đó có nghĩa là hàm strcpy () không thực hiện bất kỳ kiểm tra ranh giới nào cho mảng đích. Cuối cùng, hàm strcpy () sẽ ghi đè lên các địa chỉ bộ nhớ không được cấp phát cho mảng đích. Đây là lý do tại sao hàm strcpy () sẽ kết thúc việc ghi đè lên các vị trí bộ nhớ có thể được cấp phát cho một biến khác.

Trong ví dụ này, chúng ta có thể thấy từ đầu ra bên dưới, hàm strcpy () ghi đè lên chính chuỗi nguồn. Các lập trình viên phải luôn cẩn thận với những hành vi như vậy.

#bao gồm
#bao gồm

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';
charđích_str[5];

printf ('Trước khi gọi hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

strcpy (đích_str,source_str);

printf ('Sau khi thực hiện hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

// printf ('Địa chỉ Nguồn =% u (0x% x) n', & source_str [0], & source_str [0]);
// printf ('Địa chỉ đích =% u (0x% x) n', & destination_str [0], & destination_str [0]);

trở lại 0;
}

strcpy () - Trường hợp-2 (example3.c):

Chương trình này minh họa tình huống khi kích thước chuỗi đích lớn hơn kích thước chuỗi nguồn và chuỗi đích đã được khởi tạo với một số giá trị. Trong ví dụ này, chúng tôi đã khởi tạo:

  • source_str tới www.linuxhint.com [size = 17 + 1 = 18]
  • destination_str tới I_AM_A_DESTINATION_STRING [size = 25 + 1 = 26]

Hàm strcpy () sẽ sao chép tất cả 17 ký tự và ký tự NULL từ chuỗi nguồn sang chuỗi đích. Tuy nhiên, nó sẽ không thay thế / thay đổi các byte còn lại (Byte 19 thành 26, dựa trên một byte) trong mảng đích. Chúng tôi đã sử dụng vòng lặp for để lặp qua mảng đích và in toàn bộ mảng để chứng minh rằng các byte-19 đến 26 là không thay đổi trong mảng đích. Đó là lý do tại sao chúng ta thấy đầu ra cuối cùng là:

www.linuxhint.com_STRING .

#bao gồm
#bao gồm


/ * Chương trình này minh họa tình huống khi:

kích thước chuỗi đích> kích thước chuỗi nguồn

và chúng tôi thực thi hàm strcpy () để sao chép
chuỗi nguồn đến đích.

Lưu ý: Kích thước chuỗi đích phải luôn
lớn hơn hoặc bằng chuỗi nguồn.
* /

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';
charđích_str[26] = 'I_AM_A_DESTINATION_STRING';

printf ('Trước khi gọi hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

strcpy (đích_str,source_str);

printf ('Sau khi thực hiện hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);


/ * in chuỗi đích bằng vòng lặp for * /
printf ('In chuỗi đích char theo char: ');
printf ('NSChuỗi đích = ');

(NStôi=0;tôi<25;tôi++)
{
printf ('% NS',đích_str[tôi]);
}
printf (' ');

trở lại 0;
}

strcpy () - Trường hợp-3 (example4.c):

Chúng tôi đã coi chương trình này như một ví dụ để chỉ ra rằng chúng tôi không bao giờ nên gọi strcpy () với một chuỗi ký tự là đích. Điều này sẽ gây ra hành vi không xác định và cuối cùng, chương trình sẽ bị sập.

#bao gồm
#bao gồm

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';

printf ('Trước khi gọi hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);

/ * Không bao giờ gọi strcpy () với chuỗi ký tự là đích.
Chương trình sẽ bị sập.
* /

strcpy ('destination_str',source_str);

printf ('Sau khi thực hiện hàm strcpy (): ');
printf ('NSChuỗi nguồn =% s ',source_str);

trở lại 0;
}

strcpy () - Phiên bản do người dùng xác định (example5.c):

Trong chương trình ví dụ này, chúng tôi đã chỉ ra cách viết một phiên bản do người dùng định nghĩa của hàm strcpy ().

#bao gồm
char *strcpy_user_defined(char *đích, hăng sô char *src);

/ * Phiên bản do người dùng định nghĩa của hàm strcpy () * /
char *strcpy_user_defined(char *đích, hăng sô char *src)
{
char *dest_backup=đích;

trong khi(*src! = ' 0') / * Lặp lại cho đến khi tìm thấy ' 0'. * /
{
*đích= *src; / * Sao chép ký tự nguồn đến đích * /
src++; / * Con trỏ nguồn tăng dần * /
đích++; / * Con trỏ đích tăng dần * /
}

*đích= ' 0'; / * Chèn ' 0' vào đích một cách rõ ràng * /

trở lạidest_backup;
}

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';
charđích_str[30];

printf ('Trước khi gọi hàm sao chép chuỗi do người dùng xác định: ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

/ * Gọi hàm sao chép chuỗi do người dùng xác định * /
strcpy_user_defined(đích_str,source_str);

printf ('Sau khi thực hiện hàm sao chép chuỗi do người dùng xác định: ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

trở lại 0;
}

strcpy () - Tối ưu hóa phiên bản do người dùng xác định (example6.c):

Bây giờ, trong chương trình ví dụ này, chúng ta sẽ tối ưu hóa phiên bản strcpy () do người dùng định nghĩa.

#bao gồm
char *strcpy_user_defined(char *đích, hăng sô char *src);


/ * Phiên bản được tối ưu hóa của hàm strcpy () do người dùng xác định * /
char *strcpy_user_defined(char *đích, hăng sô char *src)
{
char *dest_backup=đích;

trong khi(*đích++ = *src++)
;

trở lạidest_backup;
}

NSchủ chốt()
{
charsource_str[] = 'www.linuxhint.com';
charđích_str[30];

printf ('Trước khi gọi hàm sao chép chuỗi do người dùng xác định: ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

/ * Gọi hàm sao chép chuỗi do người dùng xác định * /
strcpy_user_defined(đích_str,source_str);

printf ('Sau khi thực hiện hàm sao chép chuỗi do người dùng xác định: ');
printf ('NSChuỗi nguồn =% s ',source_str);
printf ('NSChuỗi đích =% s ',đích_str);

trở lại 0;
}

Phần kết luận :

Hàm strcpy () là một hàm thư viện rất phổ biến và tiện dụng để thực hiện thao tác sao chép chuỗi trong ngôn ngữ lập trình C. Điều này chủ yếu được sử dụng để sao chép chuỗi từ vị trí này sang vị trí khác. Tuy nhiên, chúng tôi muốn nhắc lại thực tế rằng hàm strcpy () không thực hiện việc kiểm tra ranh giới cho mảng đích, điều này có thể dẫn đến một lỗi phần mềm nghiêm trọng nếu bị bỏ qua. Người lập trình luôn có trách nhiệm đảm bảo mảng đích có đủ không gian để chứa tất cả các ký tự từ chuỗi nguồn bao gồm cả ký tự NULL.