如何在C++中读取二进制文件中的小端整数

ubbxdtey  于 2023-11-19  发布在  其他
关注(0)|答案(3)|浏览(127)

我一直试图读取一个小端二进制文件。我希望首先找到一个字符串的文件中的索引,从那里我可以开始阅读数据。一旦我得到的索引,我将期待提取学生信息。我已经成功地在阅读字符串(名字和姓氏)。然而,我无法提取整数(年龄)。我感谢您的帮助:)下面是二进制文件中学生信息部分的示例

130000004A4F484E444F45

个字符
我的代码的输出将是:

The student name is: John Doe, they are **(some character)** years old


预期产出应为:

The student name is: John Doe, they are 19 years old


年龄数据看起来像:二进制文件中的13 00 00 00应该转换为19,因为这是小端。
任何帮助将不胜感激。谢谢!

bzzcjhmw

bzzcjhmw1#

一条捷径
我假设(在我看来,这是很安全的)学生的年龄是一个小于255的正数,所以它适合一个字节。
只要读那个字节。

xoefb8l8

xoefb8l82#

一种便携式的方式来读取2的补码架构(这是几乎每一个现代计算机)的小端。
从字符缓冲区中读取4个字节:13 00 00 00,如下所示。

uint32_t age;
memcpy(&age, studentBuffer.c_str()+index, 4);
index += 4;

字符串
如果你使用的是Intel处理器,那么你可能已经完成了。由于Intel处理器是小端字节序。age将具有期望值。或者在本例中,0x 13 ==十进制19。
如果你想让你的代码在big-endian和little-endian硬件上运行,你可以这样做:

if (isBigEndian()) {
      // swap bytes
      uint32_t b1 = (age >> 24) & 0x000000ff;
      uint32_t b2 = (age >> 8) &  0x0000ff00;
      uint32_t b3 = (age << 8) &  0x00ff0000;
      uint32_t b4 = (age << 24) & 0xff000000;
      age = b1|b2|b3|b4;
 }


其中isBigEndian()可以写成如下:

bool isBigEndian() {
    uint8_t buffer[4] = {0};
    uint32_t t = 1;
    memcpy(buffer, &t, 4);
    return (buffer[0] == 0);
}

c86crjj0

c86crjj03#

下面是转换整数的代码,与系统无关:

#include <iostream>
#include <string>
#include <cstdint>
#include <stdexcept>

/**
 * Converts a string containing binary data into a 64-bit unsigned integer.
 * The string is interpreted in little endian format.
 * If the string contains fewer than 1 byte or more than 8 bytes, an exception is thrown.
 * 
 * @param binary_data The string containing the binary data.
 * @return The 64-bit unsigned integer representation of the binary data.
 */
uint64_t convertToUInt64(const std::string& binary_data) {
    if (binary_data.empty()) {
        throw std::invalid_argument("Input string must contain at least 1 byte.");
    }
    if (binary_data.size() > sizeof(uint64_t)) {
        throw std::invalid_argument("Input string must contain no more than 8 bytes.");
    }

    uint64_t value = 0;

    // Iterate over the string to construct the integer
    for (size_t i = 0; i < binary_data.size(); ++i) {
        // Cast each character to an unsigned byte and then shift it to the correct position
        value |= static_cast<uint64_t>(static_cast<uint8_t>(binary_data[i])) << (i * 8);
    }

    return value;
}

字符串
您可以使用string中的示例二进制数据调用此函数:

int main() {
    // Binary data in a string, representing the value 19 in 3 bytes (little endian)
    std::string binary_data = "\x13\x00\x00";

    // Convert the binary data to a 64-bit unsigned integer
    uint64_t value = convertToUInt64(binary_data);

    // Output the integer value
    std::cout << "The 64-bit unsigned integer value is: " << value << std::endl;

    return 0;
}


我已经展示了一个泛型函数,而不是一个只接受3个字节的函数,以防其他大小的字符串也被使用。如果你想有一个更小的整数,你可以检查整数是否低于一定的大小,然后赋值。

相关问题