首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中的Hexdump文本文件和二进制文件

C中的Hexdump文本文件和二进制文件
EN

Stack Overflow用户
提问于 2018-08-19 03:17:50
回答 1查看 2.7K关注 0票数 0

我正在用C编写代码,在文本文件和二进制文件中执行十六进制。我在文本文件中的输出是正确的,但是当我尝试在二进制文件中执行十六进制时,我得到了垃圾。如果我的代码哪一部分是错误的,我应该如何纠正我的错误,我想请求您的帮助。谢谢。

代码语言:javascript
复制
#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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-19 03:47: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草案)。另见:看看在C和C++中main()应该返回什么?

接下来,使用二进制输出,您将尝试使用%02x打印一个无符号值,但是您将传递一个有符号字符。如果char值为负值,则尝试输出符号扩展值,并输出无符号值的全部宽度(02x将将字段填充到2个字符,但不会阻止两个以上字符的打印)。您有两个选项,首先使用hh长度修饰符将类型限制为1字节,然后简单地将值转换为(unsigned char)

代码语言:javascript
复制
            printf("%02hhx ", (unsigned char)buff[i]);

你的逻辑也有点麻烦。您应该使用if ... else if ... else来处理二进制案例。此外,在任何一个i >= read || buff[i] == 0时,您都要输出两个空格,所以您还可以组合测试。

简短的重写可能如下所示(如果没有参数,则从作为第一个参数提供的文件读取-如果没有参数,则从stdin读取)。

代码语言:javascript
复制
#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前缀,则强制转换本身就足够了)

仔细考虑一下,如果你还有其他问题,请告诉我。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51914137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档