I have a program that reads the hex
of a file, modifies it, and stores the modified hex in a std::string
.
For example, how would I write this to a file
std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";
and get its value
.0n..:j..}p...?*8...3..x
in the outputted file?
I'd prefer not to use sprintf
, but I guess if it's necessary, I'll do what I must.
If I understand your question correctly you want the text converted to it's numeric equivalent and then written to file. Given the hint you provided in your question it looks like this should be done byte by byte. Below is one way to achieve this. Note the need to convert each byte from a string to an integer value.
#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);
}
}
The answer of @Peter R will lead to an output which is not 100% equal, due to the stringstream
interpreting more than one '0's in a row in an unintended way.
Example: If we want to write the hex value "00000000", the stringstream
would output " 000000".
The solution below works in every case, no matter how many zeros are contained in the hex string:
// 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));
Then you can simply write this string to a file like this:
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With