C 语言的十六进制转储程序


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 255
void hexDump (char *desc, void *addr, int len) {
    int i;
    unsigned char buffLine[17];
    unsigned char *pc = (unsigned char*)addr;

    if (desc != NULL){
       printf ("%s:n", desc);
    }

    for (i = 0; i < len; i++) {

        if ((i % 16) == 0) {
            if (i != 0)
                printf ("  %sn", buffLine);
           // if (buffLine[i]== '') break;
            if (pc[i] == 0x00) exit(0);
            // Prints the ADDRESS
            printf ("  %07x ", i);
        }
        // Prints the HEXCODES that represent each chars.
        printf ("%02x", pc[i]);
        if ((i % 2) == 1) 
            printf (" "); 

        if ((pc[i] < 0x20) || (pc[i] > 0x7e)){
            buffLine[i % 16] = '.';
        }
        else{
           buffLine[i % 16] = pc[i];
        }    

        buffLine[(i % 16) + 1] = ''; //Clears the next array buffLine

    }

    while ((i % 16) != 0) {
        printf ("   ");
        i++;
    }

    printf ("  %sn", buffLine);
}
//----------------------------------------------
int main()
    {
            FILE *ptr_file;
            char buff[SIZE];
            ptr_file =fopen("input.txt","r");
            if (!ptr_file){
            printf("returning 1");
                return 1;
            }
            memset(buff, '', sizeof( buff) );
            fgets(buff,SIZE, ptr_file);
            hexDump ("buff", &buff, sizeof (buff));
        fclose(ptr_file);
            return 0;
    }
    //*/

不起,这是我对 C 的新手,所以现在有点乱,我一直在删除部分并制作临时代码等......所以无论如何,这可以通过从输入中读取字符来工作.txt并通过打印右侧的十六进制表示和 Acii 表示来输出它。对于形成不可打印字符的字节,请打印"."字符(点/句点字符,即十六进制值 2E(。

0003540: 0504 0675 6e73 6967 6e65 6420 6368 6172 ...unsigned char
0003550: 0008 0107 0000 0131 0675 6e73 6967 6e65 .......1.unsigne

但是我的程序不会打印文本中"新行"以外的任何内容。例如:在我的输入.txt中,我有:

This is line 1 so this will be longer than usual
line 2 is this
this is the last line

阅读我的程序后,它只输出如下:

  0000000 5468 6973 2069 7320 6c69 6e65 2031 2073   This is line 1 s
  0000010 6f20 7468 6973 2077 696c 6c20 6265 206c   o this will be l
  0000020 6f6e 6765 7220 7468 616e 2075 7375 616c   onger than usual
  0000030 0a00 0000 0000 0000 0000 0000 0000 0000   ................

但是由于某种原因,它不会打印并十六进制第二行,第三行....

你应该使用 fread() 来读取文件,并将其放在一个循环中(直到它返回 0(,以便它读取整个文件。如果您在Windows上,还要确保使用" rb"(二进制模式(打开文件,而在Unix上则无关紧要。

最后一个建议是使用isascii()或其姊妹功能之一,而不是手动检查"可打印性"。请参阅 http://linux.die.net/man/3/isalnum。

你只调用fgets一次。 fgets从文件中读取一行,并在耗尽SIZE字符限制、到达文件末尾或遇到换行符时停止。因此,这种行为是可以预期的。

数据的长度通常小于字符限制,但您打印所有SIZE个字符,这将为您提供零。

如果要处理所有行,则应在循环中计算fgets,并在返回NULL时将其断开。您还应该传递strlen(buf)作为长度参数而不是 sizeof(buf) ,这将为您提供通常过长的SIZE

十六进制转储程序的目的是使任何文件的数据可见。您使用 fgetschar ,它们应该用于文本文件。(例如,我不确定fgets遇到空字节时会做什么。

因此,最好使用字节,即unsigned char并使用fread逐块读取它们。如果将块大小设置为 16 的倍数,这将帮助您格式化输出。所以:

for (;;) {
    unsigned char buf[SIZE];
    size_t n = fread(buf, 1, SIZE, f);
    if (n > 0) dump(buf, n);
    if (n < SIZE) break;
}
您需要

使用"rb"而不是"r"以二进制模式打开文件

然后使用 fread(( 从文件中读取,方法是从中读取块或读取整个文件。

void HexDump(const void* data, size_t size) 
{
    char ascii[17];
    size_t i, j;
    ascii[16] = '';
    for (i = 0; i < size; ++i) {
        printf("%02X ", ((unsigned char*)data)[i]);
        if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
            ascii[i % 16] = ((unsigned char*)data)[i];
        } else {
            ascii[i % 16] = '.';
        }
        if ((i+1) % 8 == 0 || i+1 == size) {
            printf(" ");
            if ((i+1) % 16 == 0) {
                printf("|  %s n", ascii);
            } else if (i+1 == size) {
                ascii[(i+1) % 16] = '';
                if ((i+1) % 16 <= 8) {
                    printf(" ");
                }
                for (j = (i+1) % 16; j < 16; ++j) {
                    printf("   ");
                }
                printf("|  %s n", ascii);
            }
        }
    }
}

您需要将输入作为缓冲区地址和缓冲区的大小,您可以看到如下所示的输出

01 0F 30 36  20 32 35 33  32 20 34 34  31 33 20 31    ..06.2532.4413.1
37 02 05 01  A0 58 6A 59  06 01 00 30  08 10 00 00    7....XjY...0....
02 7C AB B6  67                                      .|..g

最新更新