2011-01-04 37 views
13

Tôi làm cách nào để truy cập s[7] trong s?Sự khác biệt giữa strncpy và memcpy?

Tôi không quan sát thấy bất kỳ sự khác biệt nào giữa strncpymemcpy. Nếu tôi muốn in đầu ra s, cùng với s[7] (như qwertyA), những thay đổi tôi phải thực hiện trong đoạn mã sau là gì:

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
    char s[10] = "qwerty", str[10], str1[10]; 
    s[7] = 'A'; 
    printf("%s\n",s); 
    strncpy(str,s,8); 
    printf("%s\n",str); 
    memcpy(str1,s,8); 
    printf("%s\n",str1); 
    return 0; 
} 
/* 
O/P 
qwerty 
qwerty 
qwerty 
*/ 
+1

Hãy thử trao đổi 'memcpy' và' strncpy' trong mã trên của bạn. Sau đó, trải nghiệm sự khác biệt. –

+0

Sự khác biệt khác là kiểm tra kiểu và loại trả về. Quan trọng trong các trường hợp khác, không phải ở đây. – chux

Trả lời

6

Bạn đang nhận được đầu ra querty vì chỉ số 7 là không chính xác (mảng được lập chỉ mục từ 0, không phải 1). Có một số null-terminator tại chỉ số 6 để báo hiệu kết thúc của chuỗi và bất kỳ điều gì xuất hiện sau nó sẽ không có hiệu lực.

Hai điều bạn cần phải sửa chữa:

  1. Thay đổi 7 trong s[7]-6
  2. Thêm một null-terminator tại s[7]

Kết quả sẽ là:

char s[10] = "qwerty"; 
s[6] = 'A'; 
s[7] = 0; 

Original not workingfixed working.

Đối với câu hỏi là strncpy so với memcpy, sự khác biệt là strncpy thêm một trình kết thúc null cho bạn. NHƯNG, chỉ khi chuỗi nguồn có một trước n. Vì vậy, strncpy là những gì bạn muốn sử dụng ở đây, nhưng phải rất cẩn thận với NHƯNG lớn.

2

Để làm cho "qwertyA" bạn cần phải thiết lập s[6] = 'A's[7]='\0'

Strings được lập chỉ mục từ 0, vì vậy s[0] == 'q', và họ cần phải được chấm dứt null.

+0

Tôi không nên thay đổi s [7] thành s [6]. Nếu chúng ta đặt s [6] là 'A' thì chúng ta sẽ nhận được kết quả mong muốn .. – user559208

+3

@user vì vậy bạn đang nói bạn * không * muốn kết quả mong muốn? O_o –

+0

@ user559208: khi marcog viết "change' s [6] 'to' s [7] '" Tôi nghĩ anh ta thực sự có nghĩa là thay vì viết s [7], viết s [6]. Ngoài ra, đừng quên kết thúc null của chuỗi (thiết lập 's [7]' thành '0' hoặc' '\ 0'') bởi vì điều đó sẽ giúp ngăn chặn các lỗi bị tràn vào. –

20

Những người khác đã chỉ ra các vấn đề chấm dứt vô hiệu của bạn. Bạn cần hiểu sự chấm dứt vô hiệu trước khi bạn hiểu sự khác biệt giữa memcpystrncpy.

Sự khác biệt là memcpy sẽ sao chép tất cả N ký tự bạn yêu cầu, trong khi strncpy sẽ sao chép tối đa null terminator bao gồm, hoặc N ký tự, tùy theo số nào ít hơn. (Nếu nó sao chép ít hơn N ký tự, nó sẽ pad phần còn lại ra với các ký tự null.)

+6

Có một sự khác biệt nữa, strncpy sẽ lấp đầy phần còn lại của không gian bằng 0. ví dụ: nếu bạn làm 'strncpy (a, b, 255);' và a dài 10, strncpy sẽ sao chép 10 ký tự đó và điền 240 ký tự còn lại bằng 0. – nos

+0

@nos: Tôi nhận ra rằng trước khi bạn đã làm và chỉnh sửa nó trong . Nhưng dù gì cũng cảm ơn :) –

2

Khi bạn có:

char s[10] = "qwerty"; 

đây là những gì mảng chứa:

 
s[0] 'q' 
s[1] 'w' 
s[2] 'e' 
s[3] 'r' 
s[4] 't' 
s[5] 'y' 
s[6] 0 
s[7] 0 
s[8] 0 
s[9] 0 

Nếu bạn muốn thêm một 'A' đến cuối chuỗi của bạn, đó là lúc chỉ số 6 , vì các chỉ mục mảng bắt đầu tại 0

s[6] = 'A'; 

Lưu ý rằng khi bạn khởi tạo một mảng theo cách này, khoảng trắng còn lại được đặt thành 0 (không phải là t erminator), Trong khi không cần thiết trong trường hợp này, thường được nhận thức rằng bạn cần phải làm cho dây của bạn nul chấm dứt. ví dụ:

char s[10]; 
strcpy(s,"qwerty"); 
s[6] = 'A'; 
s[7] = 0; 

Trong ví dụ trên "qwerty", bao gồm trình kết thúc nul được sao chép tới s. s [6] ghi đè lên rằng ninator terminator. Vì phần còn lại của s không được khởi tạo nên chúng tôi cần thêm một phần tử cuối cùng của chúng tôi với s[7] = 0;

2

Strncpy sẽ sao chép lên đến NULL thậm chí bạn đã chỉ định số byte sao chép, nhưng memcpy sẽ sao chép tới số byte được chỉ định.

tuyên bố printf sẽ in lên đến NULL, do đó bạn sẽ cố gắng in một charater duy nhất, nó sẽ hiển thị,

printf("\t%c %c %c\t",s[7],str[7],str1[7]); 

OUTPUT

7    7 
Các vấn đề liên quan