我一直在互联网上搜索一种用c++读取二进制文件的方法,并且我发现了两个可以工作的代码片段:

1号

#include <iostream>
#include <fstream>

int main(int argc, const char *argv[])
{
   if (argc < 2) {
      ::std::cerr << "Usage: " << argv[0] << "<filename>\n";
      return 1;
   }
   ::std::ifstream in(argv[1], ::std::ios::binary);
   while (in) {
      char c;
      in.get(c);
      if (in) {
         // ::std::cout << "Read a " << int(c) << "\n";
         printf("%X ", c);
      }
   }
   return 0;
}

结果:
6C 1B 1 FFFFFFDC F FFFFFFE7 F 6B 1

2号
#include <stdio.h>
#include <iostream>

using namespace std;

// An unsigned char can store 1 Bytes (8bits) of data (0-255)
typedef unsigned char BYTE;

// Get the size of a file
long getFileSize(FILE *file)
{
    long lCurPos, lEndPos;
    lCurPos = ftell(file);
    fseek(file, 0, 2);
    lEndPos = ftell(file);
    fseek(file, lCurPos, 0);
    return lEndPos;
}

int main()
{
    const char *filePath = "/tmp/test.bed";
    BYTE *fileBuf;          // Pointer to our buffered data
    FILE *file = NULL;      // File pointer

    // Open the file in binary mode using the "rb" format string
    // This also checks if the file exists and/or can be opened for reading correctly
    if ((file = fopen(filePath, "rb")) == NULL)
        cout << "Could not open specified file" << endl;
    else
        cout << "File opened successfully" << endl;

    // Get the size of the file in bytes
    long fileSize = getFileSize(file);

    // Allocate space in the buffer for the whole file
    fileBuf = new BYTE[fileSize];

    // Read the file in to the buffer
    fread(fileBuf, fileSize, 1, file);

    // Now that we have the entire file buffered, we can take a look at some binary infomation
    // Lets take a look in hexadecimal
    for (int i = 0; i < 100; i++)
        printf("%X ", fileBuf[i]);

    cin.get();
    delete[]fileBuf;
        fclose(file);   // Almost forgot this
    return 0;
}

结果:
6C 1B 1 DC F E7 F 6B 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A1 D 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
xxd /tmp/test.bed的结果:
0000000: 6c1b 01dc 0fe7 0f6b 01                   l......k.
ls -l /tmp/test.bed的结果
-rw-rw-r-- 1 user user 9 Nov  3 16:37 test.bed

第二种方法是在开头提供正确的十六进制代码,但似乎文件大小错误,第一种方法是弄乱字节。

这些方法看起来很不一样,也许在c++中有很多方法可以做同样的事情?专业人士有习惯用法吗?

最佳答案

您当然要在将char对象处理为整数值之前将其转换为unsigned char!问题在于char可能会被签名,在这种情况下,当您将它们转换为负值时,它们会转换为负int。显示为十六进制的int负数将具有两个以上的十六进制数字,前导数字可能全为“f”。

我没有立即发现为什么第二种方法会导致尺寸错误。但是,C++读取二进制文件的方法很简单:

#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>

std::vector<unsigned char> bytes;
{
    std::ifstream in(name, std::ios_base::binary);
    bytes.assign(std::istreambuf_iterator<char>(in >> std::noskipws),
                 std::istreambuf_iterator<char>());
}
std::cout << std::hex << std::setfill('0');
for (int v: bytes) {
    std::cout << std::setw(2) << v << ' ';
}

关于c++ - 在C++中读取二进制文件的正确方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19758843/

10-11 22:38
查看更多