簡體   English   中英

將二進制文件復制到 c 中的緩沖區的正確方法

[英]correct way to copy binary file to buffer in c

我正在嘗試打開一個 bin 文件並將其數據放入緩沖區並將數據從該緩沖區復制到我制作的名為.my_data 的部分。 當我做 hexdump binfile.bin 我看到

   00000000 4455 e589 00bf 0000 e800 0000 00b8
   00000010 5d00 00c3
   00000015

當我 printf 緩沖區和緩沖區2 我看到

   55 48 89 e5 bf 00 00 00 00 e8 00 00 00 00 b8 00 00 00 00 5d c3 

   55 48 89 e5 bf 00 00 00 00 e8 00 00 00 00 b8 00 00 00 00 5d c3

它與來自 hexdump 的 output 匹配。 但是,當將 buffer2 加載到我的新部分(我沒有包含該部分代碼)時,我使用了 objdump -s -j.my_data foo 並且我看到了一些與上面的 output 不相似的其他數據。

我為這個愚蠢的問題道歉,但我只是想確認我使用的 memcpy 是否實際上將數據從緩沖區復制到緩沖區 2,因此我可以丟棄這部分並在我的程序的 rest 中查找錯誤。 從第二個 for 循環的 output 我認為是。 我也在使用 gcc,謝謝。

   #include <stdio.h>
   #include <stdint.h>
   #include <string.h>
   #include <stdlib.h>
   
   int main (){

   uint8_t buffer[21];
   uint8_t buffer2[21];
   FILE *ptr;
   ptr = fopen("binfile.bin", "rb");
   size_t file_size = 0;
   
   if(!ptr)
   {
     printf("unable to open file");
     return 1;
   }

   fseek(ptr, 0, SEEK_END);
   file_size = ftell(ptr); 
   rewind(ptr);

   int i = 0;
   
   fread(buffer, sizeof(buffer), 1, ptr);
   memcpy(buffer2, buffer, sizeof(buffer));

   for(i = 0; i < 21; i++)
   {
    printf("%02x ", buffer[i]);
   }

   printf("\n\n");
   for(i = 0; i < 21; i++)
   {
    printf("%02x ", buffer2[i]);
   }

   fclose(ptr);
  
   return 0;

   }

    

您正在考慮如何將buffer復制到buffer2 ,但您無法確保僅嘗試訪問有效初始化的buffer元素。 由於您的文件僅包含20個字節,因此當您嘗試訪問buffer[20]時,您正在嘗試訪問具有自動存儲持續時間的變量,而該值不確定調用Undefined Behavior 所有的賭注都取消了。

您可以通過完全初始化buffer來處理這個問題,例如

uint8_t buffer[21] = {0);

如果你用fread填充的元素少於所有元素仍然可以,因為所有元素都已有效初始化。

另一種方法是簡單地使用將fread設置為1size參數進行讀取,因此fread返回讀取的字節數。 然后您可以將該值用於 output 您的結果,例如

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXC 1024       /* max number of characters (bytes) */

int main (int argc, char **argv) {
    
    size_t nbytes = 0;
    unsigned char buf1[MAXC] = {0}, buf2[MAXC] = {0};
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;
    
    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }
    
    nbytes = fread (buf1, 1, MAXC, fp);     /* with size=1, no. of bytes returned */
    
    if (fp != stdin)                        /* close file if not stdin */
        fclose (fp);
    
    memcpy (buf2, buf1, nbytes);            /* copy nbytes buf1, buf2 */
    
    for (size_t i = 0; i < nbytes; i++)     /* outuput buf1 contents */
        printf (" %02x", buf1[i]);
    putchar ('\n');

    for (size_t i = 0; i < nbytes; i++)     /* output buf2 contents */
        printf (" %02x", buf2[i]);
    putchar ('\n');
}

示例使用/輸出

使用文件dat/bytes20.bin中的數據,您將收到:

$ ./bin/fread_bytes dat/bytes20.bin
 44 55 e5 89 00 bf 00 00 e8 00 00 00 00 b8 5d 00 00 c3
 44 55 e5 89 00 bf 00 00 e8 00 00 00 00 b8 5d 00 00 c3

如果您還有其他問題,請告訴我。

這是更正的代碼:打印時注意 & 0xFF

uint8_t buffer[21];
uint8_t buffer2[21];
FILE *ptr;
ptr = fopen("binfile.bin", "rb");
size_t file_size = 0;

if (!ptr)
{
    printf("unable to open file");
    return 1;
}

fseek(ptr, 0, SEEK_END);
file_size = ftell(ptr);
rewind(ptr);

int i = 0;

fread(buffer, sizeof(buffer), 1, ptr);
memcpy(buffer2, buffer, sizeof(buffer));

for (i = 0; i < sizeof buffer; i++)
{
    printf("%02x ", buffer[i] & 0xFF);
}

printf("\n\n");
for (i = 0; i < sizeof buffer2; i++)
{
    printf("%02x ", buffer2[i] & 0xFF);
}

fclose(ptr);

return 0;

這是 output

55 48 89 e5 bf 00 00 00 00 e8 00 00 00 00 b8 00 00 00 00 5d c3

55 48 89 e5 bf 00 00 00 00 e8 00 00 00 00 b8 00 00 00 00 5d c3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM