2

I am trying to read a file which contains bytes into a hex string.

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);

However the hex_data does not look like a hex string. Is there a way to convert the bytes to a hex string during reading?

6
  • Please show the input and output. Commented May 11, 2021 at 16:55
  • 1
    The std::string constructor that you are using requires a null terminated char array. Commented May 11, 2021 at 16:56
  • 1
    int length = 10; char char_arr[length]; is not standard C++, see Why aren't variable-length arrays part of the C++ standard?. Either make length const, or else use new[] or better std::vector. Commented May 11, 2021 at 16:57
  • 1
    @AndreasWenzel only if you use the constructor that takes just a char* by itself. There is another constructor that accepts a length Commented May 11, 2021 at 16:57
  • @drescherjm the input file is binary, so there may not even be any "lines" to read from it. But, of course, there are ways to read from a binary data directly into a std::string. But that is pretty moot in this case. Commented May 12, 2021 at 17:00

2 Answers 2

3

You are reading in raw bytes and storing them as-is into your std::string. If you want the std::string to be hex formatted, you need to handle that formatting yourself, eg:

#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();
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

0

use std::stringstream object

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

3 Comments

You should use std::ostringstream instead for output-only operations like this. But more important, if the char is signed, and its high bit is 1, this will cause the int to sign-extend, producing unwanted results. For example, 0x80 will be printed as ff80. Use unsigned chars instead to avoid that.
I tried your code with static_cast<unsigned short>(char(0x80)) but the result also ff80 I had to go through a double conversion to break the effect of the strong point bit: static_cast<int>(static_cast<unsigned char>(char(0x80)))
Yes, scaling up a signed char to an unsigned short performs sign-extension, because the char is promoted to int first, then the result is casted. See Standard C++ Behavior of Signed Char to Unsigned Int Conversion. But note that in my code example, the data starts out as unsigned char to begin with, so the bytes don't need an extra cast to unsigned before then casted to unsigned short.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.