2014-12-01 119 views
3

我有以下代碼。我試圖將一個結構複製到一個字符串。我想了解爲什麼輸出在strncpy和memcpy之間變化。用於結構複製的memcpy和strncpy的區別

#include <stdio.h> 
#include<string.h> 
struct a{ 
    int len; 
    int type; 
}; 
int main(){ 
    struct a aa={98,88}; 
    char str[10]=""; 
    char str2[10]=""; 

    strncpy(str,&aa,sizeof(struct a)); 
    memcpy(str2,&aa,sizeof(struct a)); 
    for(int i=0;i<10;i++)printf("%2d",str[i]); 
    printf("\n"); 
    for(int i=0;i<10;i++)printf("%2d",str2[i]); 

    return 0; 
} 

下面是輸出:

98 0 0 0 0 0 0 0 0 0 
98 0 0 088 0 0 0 0 0 

我明白strncpy()函數將複製直到遇到 '\ 0'(或大小限),但我沒有 '\ 0' 值在結構中。有人可以幫助我理解這一點。 這樣做的目的:試圖通過網絡發送結構。雖然我打算實現系列化,我想了解的行爲

編輯: 1)由基思·湯普森

建議下面是生成警告。

incompatible pointer types passing 'struct a *' to parameter of type 'const char *' [-Wincompatible-pointer-types] 

2)I修改代碼中的位,以使用int數組:

(把此供參考我明白,在這種情況下,memcpy的拷貝結構體中的前兩個元素的變量。陣列的大小是足夠的結構變量)

#include <stdio.h> 
#include<string.h> 
struct a{ 
    int len; 
    int type; 
}; 
int main(){ 
    struct a aa={98,88}; 
    int str[10]={0}; 
    int str2[10]={0}; 

    strncpy(str,&aa,sizeof(struct a)); 
    memcpy(str2,&aa,sizeof(struct a)); 
    for(int i=0;i<10;i++)printf("%2d",str[i]); 
    printf("\n"); 
    for(int i=0;i<10;i++)printf("%2d",str2[i]); 

    return 0; 
} 

下面是鄰\號碼:

98 0 0 0 0 0 0 0 0 0 
9888 0 0 0 0 0 0 0 0 

下面生成的警告:

incompatible pointer types passing 'int [10]' to parameter of type 'char *' [-Wincompatible-pointer-types] 
incompatible pointer types passing 'struct a *' to parameter of type 'const char *' [-Wincompatible-pointer-types] 
+0

您的結構不是字符串。 'strncpy'對字符串進行操作。這個電話甚至不應該編譯;你至少應該得到一個'struct a *'參數傳遞給'strncpy'的警告,它需要'char *'。即使對於字符串,通常也應該避免使用「strncpy」。 [見我在這裏主題的咆哮](http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html)。 – 2014-12-01 20:08:26

+0

它的確發出了警告。 – mayur 2014-12-02 10:49:19

+0

請更新您的問題以顯示確切的警告;這是非常重要的信息。 – 2014-12-02 14:54:12

回答

2

但我在結構中沒有'\ 0'值。

事實上,你必須至少六個'\0' -s有:假設int是32位,上三個字節都9888的都是零。他們會讓strncpy停止複製。該函數是爲固定長度的字符串設計的,因此不應該將其與任意struct s一起使用。另一方面,memcpy將複製一切。

這樣做的目的:試圖通過網絡發送結構。

如果你想在網絡的struct送過來,和你想的包是便攜式的,都轉換int s到網絡上的發送方訂單,並返回到硬件以便在接收端。對於32位數字,請使用htonl and ntohl functions

+0

謝謝,錯過了'\ 0'等於0.strcpy會停在0。 – mayur 2014-12-02 06:53:59

1

的memcpy拷貝字節,strcpy的副本空終止字符串(NUL是0字節,0×00, '\ X00')

的memcpy總是拷貝指定的字節數。 strcpy停止複製,當它發現nul

1

但我沒有在結構中的'\ 0'值。

是的,你這樣做。您的整數值有0位,當字節數據被解釋爲字符時,可將其解釋爲'\0'。由於strncpy「按字符直到達到終止符」起作用,這導致它提前停止。

memcpy複製指定的字節數,總是,這使它工作。在這種情況下更合適。

+0

謝謝,錯過了'\ 0'等於0 – mayur 2014-12-02 06:54:54