【问题标题】:Writing hex to a file将十六进制写入文件
【发布时间】:2014-03-16 04:48:16
【问题描述】:

我有一个程序可以读取文件的hex,对其进行修改,并将修改后的十六进制存储在std::string 中。

例如,我如何将其写入文件

std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";

并得到它的值

.0n..:j..}p...?*8...3..x

在输出的文件中?

我不想使用sprintf,但我想如果有必要,我会做我必须做的。

【问题讨论】:

  • 文件的十六进制”是什么意思?您是在考虑文件的二进制、未格式化的内容,还是单个十六进制值?
  • 内容,全部转换为十六进制。我是这个知识领域的新手,所以...
  • 如果我理解正确,您是在读取二进制文件,将数据存储为十六进制字符串,然后要将修改后的数据写回文件(以二进制形式)?跨度>
  • 定义二进制文件。老实说,它不是一个专门格式化的文件。所以从某种意义上说,是的。
  • 二进制文件的意思是“不是文本文件”。所有文件都是二进制文件,但文本文件意味着内容将被解释为可打印的文本数据。

标签: c++ string file hex


【解决方案1】:

如果我正确理解您的问题,您希望将文本转换为等效的数字,然后写入文件。鉴于您在问题中提供的提示,看起来应该逐字节完成。以下是实现此目的的一种方法。注意需要将每个字节从字符串转换为整数值。

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <ios>

std::string wut = "b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";

int main()
{
    std::ofstream datafile("c:\\temp\\temp1.dat", std::ios_base::binary | std::ios_base::out);

    char buf[3];
    buf[2] = 0;

    std::stringstream input(wut);
    input.flags(std::ios_base::hex);
    while (input)
    {
        input >> buf[0] >> buf[1];
        long val = strtol(buf, nullptr, 16);
        datafile << static_cast<unsigned char>(val & 0xff);
    }

}

【讨论】:

  • 小心!如果在连续两个或多个 '0' 的链中的十六进制字符串中有零,这将不起作用!请参阅我在下面提供的另一种可能的解决方案,假设十六进制字符串的长度是偶数,它将在 100% 的时间内起作用。
【解决方案2】:

@Peter R 的答案将导致输出不是 100% 相等,因为 stringstream 以非预期方式连续解释多个 '0。

示例:如果我们要写入十六进制值“00000000”,stringstream 将输出“000000”。

以下解决方案适用于所有情况,无论十六进制字符串中包含多少个零

// Input
std::string hex = "180f00005e2c3415"; // (or longer)

std::basic_string<uint8_t> bytes;

// Iterate over every pair of hex values in the input string (e.g. "18", "0f", ...)
for (size_t i = 0; i < hex.length(); i += 2)
{
    uint16_t byte;

    // Get current pair and store in nextbyte
    std::string nextbyte = hex.substr(i, 2);

    // Put the pair into an istringstream and stream it through std::hex for
    // conversion into an integer value.
    // This will calculate the byte value of your string-represented hex value.
    std::istringstream(nextbyte) >> std::hex >> byte;

    // As the stream above does not work with uint8 directly,
    // we have to cast it now.
    // As every pair can have a maximum value of "ff",
    // which is "11111111" (8 bits), we will not lose any information during this cast.
    // This line adds the current byte value to our final byte "array".
    bytes.push_back(static_cast<uint8_t>(byte));
}

// we are now generating a string obj from our bytes-"array"
// this string object contains the non-human-readable binary byte values
// therefore, simply reading it would yield a String like ".0n..:j..}p...?*8...3..x"
// however, this is very useful to output it directly into a binary file like shown below
std::string result(begin(bytes), end(bytes));

然后你可以简单地将这个字符串写到这样的文件中:

std::ofstream output_file("filename", std::ios::binary | std::ios::out);
if (output_file.is_open())
{
    output_file << result;
    output_file.close();
}
else
{
    std::cout << "Error could not create file." << std::endl;
}

【讨论】:

  • 它工作得很好,你介意解释一下逻辑吗?
  • @DanielSelvan 添加了 cmets
猜你喜欢
  • 2015-08-22
  • 2015-01-03
  • 2013-07-11
  • 2011-12-22
  • 1970-01-01
  • 2013-01-07
  • 2021-10-27
  • 2013-05-03
  • 2013-05-03
相关资源
最近更新 更多