You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux下使用C语言将二进制文件转换为可读文本文件的问题

二进制转可读文本的正确实现思路

兄弟,你当前的代码核心问题是完全没做转换操作——它只是把输入的二进制文件原封不动地复制到输出文件,本质上还是二进制内容,自然没法直接读。我来给你拆解正确的做法:

先搞清楚你的需求

二进制转可读文本通常分两种场景,你得先对应上自己的情况:

  • 场景1:二进制是纯数据(比如内存镜像、自定义数据库文件)→ 转成十六进制格式(最通用的可读方式)
  • 场景2:二进制本质是文本(只是被以二进制模式存储)→ 提取其中的可打印字符

场景1:转换为十六进制格式(通用方案)

这种方式会把每个字节转换成两位十六进制字符,同时附带ASCII可视字符,和你用hexdump命令的效果类似,非常适合查看二进制数据。

#include <stdio.h>
#include <ctype.h>

int main() {
    unsigned char buffer[16]; // 每次读16字节,方便按行格式化
    FILE *input = fopen("memdb", "rb");
    FILE *output = fopen("output.out", "w"); // 用文本模式写输出

    // 先判断文件是否打开成功
    if (!input || !output) {
        perror("Failed to open file");
        return 1;
    }

    size_t bytes_read;
    unsigned long offset = 0;
    // 正确的循环方式:用fread的返回值判断是否还有数据
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), input)) > 0) {
        // 1. 打印偏移地址(方便定位)
        fprintf(output, "%08lx: ", offset);
        // 2. 打印十六进制字节
        for (size_t i = 0; i < sizeof(buffer); i++) {
            if (i < bytes_read) {
                fprintf(output, "%02x ", buffer[i]);
            } else {
                fprintf(output, "   "); // 不足16个字节时补空格对齐
            }
        }
        // 3. 打印对应的ASCII可打印字符(不可打印的用.代替)
        fprintf(output, "| ");
        for (size_t i = 0; i < bytes_read; i++) {
            fprintf(output, "%c", isprint(buffer[i]) ? buffer[i] : '.');
        }
        fprintf(output, "\n");
        offset += bytes_read;
    }

    fclose(input);
    fclose(output);
    return 0;
}

这段代码的关键改进:

  • "w"打开输出文件,确保写入的是文本格式
  • 替换了错误的while(!feof(input))——这个写法会导致多循环一次,因为feof要在读取失败后才会触发
  • 加入了错误判断,避免文件打开失败时崩溃
  • 做了真正的转换:把二进制字节转成十六进制字符串+可视ASCII

场景2:提取二进制中的文本内容

如果你的memdb其实是文本文件,只是被以二进制方式存储,那可以直接提取其中的可打印字符:

#include <stdio.h>
#include <ctype.h>

int main() {
    char buffer[1000];
    FILE *input = fopen("memdb", "rb");
    FILE *output = fopen("output.out", "w");

    if (!input || !output) {
        perror("Failed to open file");
        return 1;
    }

    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), input)) > 0) {
        for (size_t i = 0; i < bytes_read; i++) {
            // 保留可打印字符和换行/回车符
            if (isprint(buffer[i]) || buffer[i] == '\n' || buffer[i] == '\r') {
                fputc(buffer[i], output);
            }
            // 可选:把不可打印字符替换成.或空格
            // else {
            //     fputc('.', output);
            // }
        }
    }

    fclose(input);
    fclose(output);
    return 0;
}

最后再提一下你原代码的问题

你的原代码用rb读、wb写,循环里直接freadfwrite,本质就是二进制文件复制,和“转可读文本”没有任何关系,所以不管怎么试都不会得到可读的内容。

内容的提问来源于stack exchange,提问作者sixstring

火山引擎 最新活动