簡體   English   中英

關於 C 中 printf() 的混淆

[英]confusion about printf() in C

我正在嘗試使用以下代碼對文件進行 hexdump:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 16

void pre_process(char buffer[],int len);

int main(int argc, char **argv){
    if(argc == 2){
        char *file = argv[1];
        FILE *input = fopen(file,"r");
        char buffer[SIZE];
        char *tmp = malloc(4);
        while(!feof(input)){ 
            printf("%06X  ",ftell(input)); /*print file pos*/
            fread(buffer,1,SIZE,input); /*read 16 bytes with buffer*/
           
            for (int i=0;i<SIZE;i += 4){ /*print each 4 bytes with hex in buffer*/
                memcpy(tmp,buffer+i,4);
                printf("%08X  ",tmp);
            }
            printf("*");
            pre_process(buffer,SIZE); /*print origin plain-text in buffer. subsitute unprint char with '*' */
            printf("%s",buffer);
            printf("*\n");
        }
        free(tmp);
        fclose(input);
   }
}

void pre_process(char buffer[],int len){
    for (int i=0;i<len;i++){
        if(isblank(buffer[i]) || !isprint(buffer[i]))
            buffer[i] = '*';
    }
}

從指環王那里讀取切片,結果如下:在此處輸入圖像描述

那么,為什么十六進制代碼都一樣? printf("%08X ",tmp);看起來有問題謝謝你的幫助。

答案就在這里:

memcpy(tmp,buffer+i,4);
printf("%08X  ",tmp);

您可能已經知道memcpy4個字節從buffer+i復制到tmp指向的位置。

即使這是在循環中完成的, tmp仍會繼續保存特定位置的地址,該地址永遠不會改變。 每次調用memcpy()都會更新 memory 中該地址/位置的內容。

簡而言之,房子只留在那里,因此地址保持不變,但人們換了地方,新的人來了,老的人被消滅了!

此外,這里還有很多需要改進/修復的地方。 我建議從編譯器的-Wall選項啟用警告開始。

tmp存儲緩沖區的地址 該地址永遠不會改變。 您要打印的是tmp指向的緩沖區的內容。 在這種情況下, tmp指向一個 4 char的緩沖區; 如果你寫

printf( "%08X ", *tmp );

您將只打印第一個元素的值 - 由於tmp的類型為char * ,因此表達式*tmp的類型為char並且等效於編寫tmp[0]

要將這些字節中的內容視為unsigned int (這是%X轉換說明符所期望的),您需要在取消引用之前指針轉換為正確的類型:

printf( "%08X ", *(unsigned int *) tmp );

我們首先必須將tmpchar *轉換為unsigned int * ,然后取消引用結果以獲得這四個字節的unsigned int等價物。

這假設您的系統上的sizeof (unsigned int) == 4 - 為了安全起見,您應該將malloc調用編寫為

char *tmp = malloc( sizeof (unsigned int) );

for ( int i = 0; i < SIZE; i += sizeof (unsigned int) )
{
  memcpy( tmp, buffer + i, sizeof (unsigned int) );
  ...
}

反而。

您不應該使用feof作為循環條件 - 在您嘗試讀取文件末尾之前它不會返回 true,因此您的循環會經常執行一次。 您需要查看fread的返回值以確定您是否已到達文件末尾。

暫無
暫無

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

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