【问题标题】:hexdump program in C languageC语言的hexdump程序
【发布时间】:2014-09-22 08:15:29
【问题描述】:
#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 ("  %s\n", buffLine);
           // if (buffLine[i]== '\0') 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] = '\0'; //Clears the next array buffLine


    }



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


    printf ("  %s\n", 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, '\0', sizeof( buff) );
            fgets(buff,SIZE, ptr_file);
            hexDump ("buff", &buff, sizeof (buff));

        fclose(ptr_file);

            return 0;
    }
    //*/

抱歉,我是 C 新手,所以现在有点乱,我一直在删除部分并制作临时代码等... 所以无论如何,这通过从 input.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

但是我的程序不打印文本中“新行”之外的任何内容。 例如: 在我的 input.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   ................

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

【问题讨论】:

  • 您要么需要在循环中调用fgets,一次读取一行,要么使用fread,读取固定大小的块。

标签: c hexdump


【解决方案1】:

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

最后一个建议是使用isascii() 或其姊妹函数之一,而不是手动检查“可打印性”。见http://linux.die.net/man/3/isalnum

【讨论】:

    【解决方案2】:

    您只给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;
    }
    

    【讨论】:

      【解决方案3】:

      您需要使用“rb”而不是“r”以二进制模式打开文件

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-06
        • 1970-01-01
        • 2022-01-21
        • 2014-02-11
        • 1970-01-01
        • 2013-12-03
        • 2020-07-15
        • 1970-01-01
        相关资源
        最近更新 更多