【问题标题】:How to read bytes from file to hex string in C++?如何在 C++ 中从文件读取字节到十六进制字符串?
【发布时间】:2021-08-02 01:51:19
【问题描述】:

我正在尝试将包含字节的文件读入十六进制字符串。

std::ifstream infile("data.txt", std::ios_base::binary);

int length = 10;
char char_arr[length];
for (int i=0; i<length; i++)
{
     infile.get(char_arr[i]);
}
std::string hex_data(char_arr);

但是hex_data 看起来不像一个十六进制字符串。有没有办法在读取过程中将字节转换为十六进制字符串?

【问题讨论】:

  • 请显示输入输出。
  • 您正在使用的 std::string 构造函数需要 null 终止 char 数组。
  • int length = 10; char char_arr[length]; 不是标准 C++,请参阅 Why aren't variable-length arrays part of the C++ standard?。要么使length const,要么使用new[] 或更好的std::vector
  • @AndreasWenzel 仅当您使用仅采用 char* 本身的构造函数时。还有另一个接受长度的构造函数
  • @drescherjm 输入文件是二进制的,因此甚至可能没有任何“行”可以从中读取。但是,当然,有一些方法可以将二进制数据直接读入std::string。但在这种情况下,这是没有实际意义的。

标签: c++ char hex ifstream


【解决方案1】:

您正在读取原始字节并将它们按原样存储到您的std::string 中。如果您希望 std::string 为十六进制格式,您需要自己处理该格式,例如:

#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>

std::ifstream infile("data.txt", std::ios_base::binary);

const int length = 10;
unsigned char bytes[length];

if (infile.read(reinterpret_cast<char*>(bytes), length)) {
    size_t numRead = infile.gcount();
    std::ostringstream oss;
    for(size_t i = 0; i < numRead; ++i) {
        oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned short>(bytes[i]);
    }
    std::string hex_data = oss.str();
    ...
}

【讨论】:

    【解决方案2】:

    使用 std::stringstream 对象

    std::stringstream stream;
    stream << std::hex << static_cast<int>( your_char);
    std::string result( stream.str() );
    

    【讨论】:

    • 您应该使用std::ostringstream 而不是这样的仅输出操作。但更重要的是,如果 char 已签名,并且其高位为 1,这将导致 int 进行符号扩展,从而产生不需要的结果。例如,0x80 将打印为 ff80。使用无符号字符来避免这种情况。
    • 我用static_cast&lt;unsigned short&gt;(char(0x80)) 尝试了你的代码,但结果也是ff80 我不得不通过双重转换来打破优势位的效果:static_cast&lt;int&gt;(static_cast&lt;unsigned char&gt;(char(0x80)))
    • 是的,将 已签名 char 扩大到 unsigned short 执行符号扩展,因为 char 首先被提升为 int,然后是结果被铸造。见Standard C++ Behavior of Signed Char to Unsigned Int Conversion。但请注意,在我的代码示例中,数据以unsigned char 开头,因此字节不需要额外转换为无符号然后转换为unsigned short
    猜你喜欢
    • 2018-02-02
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2011-10-01
    • 1970-01-01
    • 2019-07-27
    相关资源
    最近更新 更多