C读取二进制文件

新手上路,请多包涵

我想了解在 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 我这样做是为了实现香农-法诺算法,所以如果有人对阅读二进制文件有任何建议,我将不胜感激。

原文由 mrNobody 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 326
1 个回答

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

 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!

原文由 Pavel P 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏