[英]Hexdump text and binary files in C
我正在用C語言編寫文本和二進制文件中的十六進制轉儲代碼。 我在文本文件中的輸出是正確的,但是當我嘗試在二進制文件中執行hexdump時,出現了垃圾。 如果我的代碼的哪一部分是錯誤的,我該如何糾正我的錯誤,我想向您尋求幫助。 謝謝。
#include <stdio.h>
#define OFFSET 16
main(int argc, char const *argv[])
{
FILE *fp;
char buff[OFFSET];
int read;
int address = 0;
int i;
if (argc != 2){
exit(0);
}
fp = fopen(argv[1], "rb");
while ((read = fread(buff, 1, sizeof buff, fp)) > 0){
printf("%08x ", address);
address += OFFSET;
//print hex values
for (i = 0; i < OFFSET; i++){
if(i >= read){
buff[i] = 0;
}
if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00){
printf("%02x ", buff[i]);
}
if(buff[i] == 00){
printf(" ");
}
}
//print ascii values
for (i = 0; i < OFFSET; i++) {
printf("%c", (buff[i] >= 33 && buff[i] <= 255 ? buff[i] : ' '));
}
printf("\n");
}
fclose(fp);
}
您在邏輯上有兩個錯誤。 首先,如注釋中所指定,二進制文件中的所有字符都同等重要。 不需要(也不應該if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00)
對二進制輸出測試if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00)
。
main
的正確聲明是int main (void)
和int main (int argc, char **argv)
(您將看到使用等效的char *argv[]
編寫)。 請參閱: C11標准§5.1.2.2.1程序啟動p1(草稿n1570) 。 另請參見: 請參見main()在C和C ++中應該返回什么?
接下來是二進制輸出,您嘗試使用%02x
打印無符號值,但是您正在傳遞帶符號的字符。 如果char
值為負,則您嘗試輸出帶符號擴展值,並輸出無符號值的完整寬度( 02x
會將字段填充為2個字符,但不會阻止打印兩個以上的字符)。 您有兩種選擇,首先使用hh
length修飾符將類型限制為1個字節,然后僅將值(unsigned char)
為(unsigned char)
,例如
printf("%02hhx ", (unsigned char)buff[i]);
您的邏輯也有點麻煩。 您應該使用if ... else if ... else
來處理二進制情況。 此外,當i >= read || buff[i] == 0
時,您將輸出兩個空格。 i >= read || buff[i] == 0
,所以您最好將測試結合起來。
簡短的重寫可能類似於以下內容(它將從作為第一個參數給出的文件中讀取-如果沒有給出參數,則將從stdin
讀取)
#include <stdio.h>
#define OFFSET 16
int main (int argc, char const *argv[])
{
char buff[OFFSET] = "";
int read, address = 0, i;
FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;
if (!fp) {
perror ("fopen");
return 1;
}
while ((read = fread(buff, 1, sizeof buff, fp)) > 0) {
printf("%08x ", address);
address += OFFSET;
for (i = 0; i < OFFSET; i++) /* print hex values */
if (i >= read || buff[i] == 0)
printf(" ");
else
printf("%02hhx ", (unsigned char)buff[i]);
fputs ("| ", stdout); /* optional separator before ASCII */
for (i = 0; i < OFFSET; i++) /* print ascii values */
printf("%c", (buff[i] >= ' ' && buff[i] <= '~' ? buff[i] : ' '));
putchar ('\n'); /* use putchar to output single character */
}
if (fp != stdin)
fclose (fp);
}
(注意:如果您的編譯器不支持hh
前綴,則強制轉換本身就足夠了)
仔細檢查一下,如果您還有其他問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.