繁体   English   中英

C ++读取二进制文件

[英]C++ reading binary files

我想了解读取二进制文件如何在C ++中工作。 我的代码:

int main() {
    ifstream ifd("input.png",ios::binary |ios::ate);
    int size = ifd.tellg();
    ifd.seekg(0,  ios::beg);
    vector<char> buffer;
    buffer.reserve(size);
    ifd.read(buffer.data(), size);

    cout << buffer.data();
    return 0;
}

我认为,如果我输入我的缓冲区,我会得到二进制的结果,但事实并非如此。

My output is: ˙Ř˙á6Exif

如果我读取文本文件,它将以正常形式显示文本而不是二进制文本。 显然我的逻辑不正确。 如何将文件读取到缓冲区以使其包含二进制值? Ps我这样做是为了实现Shannon-Fano算法,所以如果有人对阅读二进制文件有任何建议,我将不胜感激。

您需要调整矢量大小,而不是保留它:

int main()
{
    ifstream ifd("input.png", ios::binary | ios::ate);
    int size = ifd.tellg();
    ifd.seekg(0, ios::beg);
    vector<char> buffer;
    buffer.resize(size); // << resize not reserve
    ifd.read(buffer.data(), size);

    cout.write(buffer.data(), buffer.size()); // you cannot just output buffer to cout as the buffer won't have '\0' ond-of-string terminator
}

否则,您的代码会尝试将size字符读入空缓冲区。 您也可以使用设置矢量大小的向量构造函数: vector<char> buffer(size);

您可以这样输出缓冲区的字节值:

void dumpbytes(const vector<char>& v)
{
    for (int i=0; i<v.size(); ++i)
    {
        printf("%u ", (unsigned char)v[i]);
        if ((i+1) % 16 == 0)
            printf("\n");
    }
    printf("\n");
}

或者像常见的十六进制编辑器那样用于十六进制输出:

void dumphex(const vector<char>& v)
{
    const int N = 16;
    const char hex[] = "0123456789ABCDEF";
    char buf[N*4+5+2];
    for (int i = 0; i < v.size(); ++i)
    {
        int n = i % N;
        if (n == 0)
        {
            if (i)
                puts(buf);
            memset(buf, 0x20, sizeof(buf));
            buf[sizeof(buf) - 2] = '\n';
            buf[sizeof(buf) - 1] = '\0';
        }
        unsigned char c = (unsigned char)v[i];
        buf[n*3+0] = hex[c / 16];
        buf[n*3+1] = hex[c % 16];
        buf[3*N+5+n] = (c>=' ' && c<='~') ? c : '.';
    }
    puts(buf);
}

缓冲区“Hello World!” 数据印刷如下:

48 65 6C 6C 6F 20 57 6F 72 6C 64 21                  Hello World!

以二进制模式打开文件意味着您的操作系统不会透明地转换CR / LF / CRLF格式之间的行结尾。

它对你的计算机如何打印一个字符串没有任何影响,七行之后。 我不知道“得到二进制结果”是什么意思,但我建议通过以十六进制对表示方式一次打印一个组成字节来渲染vector<char>的内容:

std::cout << std::hex << std::setfill('0');
for (const auto byte : buffer)
   std::setw(2) << byte;

输出看起来像:

0123456789abcdef0123456789abcdef

每两个字符代表数据中一个字节的0-255字节值,使用base-16(或“hex”)数字系统。 这是非文本信息的常见表示。

或者, 您可以输出base-2中的数据 (字面意思是“二进制”)。

由您决定如何呈现信息。 文件打开模式与矢量无关。

你还需要修复矢量的大小; 在你打电话的那一刻。 .reserve你的意思.resize

基于Pavel回答,你也可以添加它来查看真实二进制数据,即01秒。 不要忘记包含bitset标头。

void dumpbin(const vector<char>& v)
{
    for (int i = 0; i < v.size(); ++i)
    {
        cout <<bitset<8>((unsigned char)(v[i])) << " ";
        if ((i + 1) % 8 == 0)
            printf("\n");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM