簡體   English   中英

使用C從文件讀取字節

[英]Reading Bytes from a File using C

我用C語言編寫了一個程序,它將從其自己的地址空間讀取特定內存地址的字節。

它是這樣的:

  1. 首先,它從文件讀取DWORD。
  2. 然后它將這個DWORD用作內存地址,並在當前進程的地址空間中從該內存地址讀取一個字節。

以下是代碼摘要:

FILE *fp;
char buffer[4];

fp=fopen("input.txt","rb");

// buffer will store the DWORD read from the file

fread(buffer, 1, 4, fp);

printf("the memory address is: %x", *buffer);

// I have to do all these type castings so that it prints only the byte example:
// 0x8b instead of 0xffffff8b

printf("the byte at this memory address is: %x\n", (unsigned)(unsigned char)(*(*buffer)));

// And I perform comparisons this way

if((unsigned)(unsigned char)(*(*buffer)) == 0x8b)
{
    // do something
}

當該程序工作時,我想知道是否還有另一種方法可以從特定的內存地址讀取字節並進行比較? 因為每次,我都需要編寫所有類型轉換。

另外,現在,當我嘗試使用以下語法將字節寫入文件時:

// fp2 is the file pointer for the output file
fwrite(fp2, 1, 1, (unsigned)(unsigned char)(*(*buffer)));

我得到警告:

test.c(64) : warning C4047: 'function' : 'FILE *' differs in levels of indirectio
n from 'unsigned int'
test.c(64) : warning C4024: 'fwrite' : different types for formal and actual para
meter 4

謝謝。

注意fwrite的定義,

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

這意味着問題最后部分的警告是因為您應該從字符指針進行寫入,而不是寫入字符的實際值。

您可以通過將從文件中讀取的指針分配給正確類型的另一個變量來刪除多余的類型轉換。

要考慮的示例

#include <stdio.h>
int main() {
  union {
    char buffer[8];
    char *character;
    long long number;
  } indirect;
  /* indirect is a single 8-byte variable that can be accessed
   * as either a character array, a character pointer, or as
   * an 8-byte integer! */
  char *x = "hi";
  long long y;
  char *z;
  printf("stored in the memory beginning at x: '%s'\n", x); /* 'hi' */
  printf("bytes used to represent the pointer x: %ld\n", sizeof(x)); /* 8 */
  printf("exact value (memory location) of (pointed to by) the pointer x: %p\n", x); /* 4006c8 */
  y = (long long) x;
  printf("%llx\n", y); /* 4006c8 */
  z = (char *) y;
  printf("%s\n", z); /* 'hi' */
  /* the cool part--we can access the exact same 8 bytes of data
   * in three different ways, as a 64-bit character pointer,
   * as an 8-byte character buffer, or as
   * an 8-byte integer */
  indirect.character = z;
  printf("%s\n", indirect.character); /* 'hi' */
  printf("%s\n", indirect.buffer); /* binary garbage which is the raw pointer  */
  printf("%lld\n", indirect.number); /* 4196040 */
  return 0;
}

順便說一句,從內存中讀取任意位置似乎很重要。 (您說您正在從程序自己的地址空間內的特定內存地址讀取數據,但是如何確定呢?)

您可以使用C語言聯合構造來表示類型的別名,如下所示

typedef union {
      char char[4];
      char *pointer;
   } alias;

alias buffer;

假定使用32位體系結構(您可以在編譯時調整4 ,但隨后還需要更改fread()字節數)。

然后,您可以簡單地使用*(buffer.pointer)來引用內存位置的內容。

從您的問題來看,應用程序尚不清楚,該技術似乎容易出錯。 當事情發生變化時,您如何考慮地址在內存中的移動? 使用鏈接器映射為位置提取符號信息可能會有所避開絕對地址。

    fp=fopen("input.txt","rb");

該文件的擴展名為.txt,您正在嘗試將其讀取為二進制文件。 請相應地命名文件。 如果在Windows上,請使用.bin擴展名命名二進制文件。 在Linux上文件擴展名沒關系。

    // buffer will store the DWORD read from the file

    fread(buffer, 1, 4, fp);

如果要讀取4個字節,請聲明一個未ing的int變量,並向其中讀取4個字節,如下所示

    fread(&uint, 1, 4, fp);

為什么要使用字符數組? 那是不對的。

    printf("the memory address is: %x", *buffer);

您想在這里做什么? buffer是指向const char的指針,上面的語句顯示數組中第一個字符的十六進制值。 上面的陳述等於

   printf("the memory address is: %x", buffer[0]);

   (*(*buffer)

這如何運作? 沒有編譯器警告和錯誤嗎? 是Windows還是Linux? (* buffer)是一個字符,並且再次取消引用它應該引發錯誤,除非正確地轉換(我認為您沒有這樣做)。

暫無
暫無

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

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