2012-03-11 66 views
3

似乎是一個基本的問題,但我寧願要求清除比在這上面花費更多的時間。我試圖將數據複製到我收到的緩衝區中(recv調用),然後將其推送到一個文件。我想使用memcpy連續追加/添加數據到緩衝區,直到緩衝區的大小不足以容納比使用realloc更多的數據。代碼如下。memcpy vs strcat

int vl_packetSize = PAD_SIZE + (int)p_size - 1; // PAD_SIZE is the size of char array sent 
         //p_size is the size of data to be recv. Same data size is used by send 
int p_currentSize = MAX_PROTO_BUFFER_SIZE; 
int vl_newPacketSize = p_currentSize; 

char *vl_data = (char *)malloc(vl_packetSize); 
memset((char *)vl_data,'\0',vl_packetSize); 


/* Allocate memory to the buffer */ 
vlBuffer = (char *)malloc(p_currentSize); 
memset((char *)vlBuffer,'\0',p_currentSize); 
char *vlBufferCopy = vlBuffer; 

if(vlBuffer==NULL) 
    return ERR_NO_MEM; 

/* The sender first sends a padding data of size PAD_SIZE followed by actual data. I want to ignore the pad hence do vl_data+PAD_SIZE on memcpy */ 
if((p_currentSize - vl_llLen) < (vl_packetSize-PAD_SIZE)){ 
    vl_newPacketSize +=vl_newPacketSize; 
    char *vlTempBuffer = (char *)realloc(vlBufferCopy,(size_t)vl_newPacketSize); 
    if(vlTempBuffer == NULL){ 
    if(debug > 1) 
    fprintf(stdout,"Realloc failed:%s...Control Thread\n\n",fn_strerror_r(errno,err_buff)); 
    free((void *)vlBufferCopy); 
    free((void *)vl_data); 
    return ERR_NO_MEM; 
     } 
    vlBufferCopy = vlTempBuffer; 
    vl_bytesIns = vl_llLen; 
    vl_llLen = 0; 
    vlBuffer = vlBufferCopy+vl_bytesIns; 
    fprintf(stdout,"Buffer val after realloc:%s\n\n",vlBufferCopy); 
} 

memcpy(vlBuffer,vl_data+PAD_SIZE,vl_packetSize-PAD_SIZE); 

/* 
fprintf(stdout,"Buffer val before increment:%s\n\n",vlBuffer); 
fprintf(stdout,"vl_data length:%d\n\n",strlen(vl_data+PAD_SIZE)); 
fprintf(stdout,"vlBuffer length:%d\n\n",strlen(vlBuffer)); 
*/ 

vlBuffer+=(vl_packetSize-PAD_SIZE); 
vl_llLen += (vl_packetSize-PAD_SIZE); 
vl_ifNotFlush = 1; 
//fprintf(stdout,"Buffer val just before realloc:%s\n\n",vlBufferCopy); 
} 

問題:後來我把數據輸入到文件中。只有第一個數據recv /添加到緩衝區纔會進入該文件。 另外,當我打印vlBufferCopy(它指向由malloc或realloc返回的數據的第一個位置)的值時,我會得到相同的結果。 如果我將大小減1,則可以看到文件中的全部數據,但它以某種方式錯過了新行字符,因此數據爲 未在文件中以正確的格式插入。 我知道那是因爲尾隨「\ 0」,但一些如何通過1

(vlBuffer+=(vl_packetSize-PAD_SIZE-1);) 

縮小尺寸錯過了換行字符的。的fputs而把數據刪除後的空字符 請讓我知道我在這裏失蹤檢查或在邏輯 (注:我嘗試使用的strcat:

strcat(vlBuffer,vl_data+PAD_SIZE); 

,但我想使用memcpy,因爲它速度更快,也可以用於任何一種緩衝作用,而不僅僅是字符指針

感謝

+1

不要在C程序中從'malloc()'或'realloc()'強制返回值。你也不需要在memset()或free()調用中進行強制轉換。 – 2012-03-11 07:34:12

+0

另外,你可能應該在'vlBuffer'上使用'memset'之前移動'if(vlBuffer == NULL)return ERR_NO_MEM;'。 – DCoder 2012-03-11 07:44:23

+0

@Carl Norum,@ Dcoder:謝謝你的建議。我已經相應地更改了代碼。再次感謝。 – user369823 2012-03-11 16:44:02

回答

2

strcatmemcpy有很大的不同的功能。
我建議你閱讀文檔 每個。

主要有兩點不同:在這裏你告訴它
複製數據。 strcat找到字符串的結尾,並在那裏複製。
2. memcpy複製您請求的字節數。 strcat副本直到終止爲空。

如果你正在處理任意內容的數據包,那麼你不能使用strcat或其他字符串函數。

+0

感謝您的回覆。我讀了每個文件。你使用memcpy的建議完全是我避免使用strcat的原因。但是我之前提到的問題是空字符導致fprintf和fputs函數不打印或複製整個vlBuffer內容。它首先停止null /'\ 0'值。如果我減小緩衝區(指針)增加1的大小,覆蓋最後一個空字符,它也會覆蓋新的行字符(如果有的話)。再次感謝您的回覆 – user369823 2012-03-11 16:49:48

+0

如果您未處理以空字符結尾的字符串,請勿使用任何字符串函數。這包括'fprintf'和'fputs'。改用'write'。 – ugoren 2012-03-12 13:19:11

0

您需要以二進制安全的方式寫入文件。檢查如何使用fwrite而不是fputs。即使中間有一個零,fwrite也會複製所有的緩衝區。

const char *mybuff= "Test1\0Test2"; 
const int mybuff_len = 11; 
size_t copied = fwrite(mybuff, mybuff_len, 1, output_file);