-1

I am having a string which contains the hex value:

string str = "e101";

I need to write this in a file as 2 bytes. While I am trying to write a file, it will write like the following 4 bytes value:

65 31 30 31

I am using the following operation for file write:

    myfile.open ("file.cf3",std::ios::binary);
    myfile << str << "\n";
    myfile.close();

but I want to write it as a 2 bytes value.

For example, if i g How to write it as 2 bytes to a file?

std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";

i want the output like

.0n..:j..}p...?*8...3..x
Revathi M
  • 3
  • 5
  • 1
    `fwrite` (a C funciton), does not take `std::string` as its first argument, it takes `char*`. (you will have to convert `str` to an `unsigned short` value before calling `fwrite`) and then you will write `sizeof (short)` number of bytes, not `str.size()` bytes... Also for `"65 31 30 31"` see [ASCIITable](http://www.asciitable.com/). – David C. Rankin May 10 '19 at 07:25
  • 2
    So you want the two bytes `0xe1` and `0x01` to be written into your file? Please [edit] your question and make that clear. Also your question title is misleading, this has nothing to do with SHA. – Jabberwocky May 10 '19 at 07:28
  • yes, i want to write it as only 2 bytes value – Revathi M May 10 '19 at 07:30
  • Possible duplicate of [Convert a char array to hex binary format C++](https://stackoverflow.com/questions/22680036/convert-a-char-array-to-hex-binary-format-c) – Jabberwocky May 10 '19 at 07:34
  • 1
    OK, you have tagged this question C++, but what you show is C. The languages are very different. You can call C functions in C++, but if you are supposed to write this in C++, you may want to use the C++ file stream interface instead of the C `fwrite` with [std::ios_base::openmode - binary](https://en.cppreference.com/w/cpp/io/ios_base/openmode) – David C. Rankin May 10 '19 at 07:35
  • 1
    Duplication of https://stackoverflow.com/questions/21819782/writing-hex-to-a-file-c – Yong Le Cherng May 10 '19 at 07:50
  • @RevathiM please let us know if you're writing in C or in C++. – Jabberwocky May 10 '19 at 07:53
  • i am writing in c++ only. – Revathi M May 10 '19 at 07:54
  • Like if I give a string like this **std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";** I need output as **.0n..:j..}p...?*8...3..x** – Revathi M May 10 '19 at 07:57
  • @RevathiM please don't post tons of comments, but [edit] your question and put all relevant information _there_. Also look at the duplicates mentioned in the comments. If you're writing in C++, `fwrite(str , 1 , str.size() , fptr )` is most likely wrong anyway, if it works, you have a non standard platform. – Jabberwocky May 10 '19 at 07:59

3 Answers3

1

Here is an example for a solution.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ofstream file("file.txt", std::ios::binary);
    if(!file.is_open())  {
        return -1;
    }
    std::string str("e101");
    for (std::size_t i = 0; i < str.length() - 1; ++++i) {
        file << static_cast<char>(str[i] * 16 + str[i + 1]);
    }
    file.close();
}

You can simply iterate over your string and take two characters as one byte. You multiply the first character with 16 and add the second character.

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
1

I think your question is ambiguous ... Keep in mind that, from your string, every two char you have 1 byte (not two). So you want to write two numbers (meaning in ascii) representing the hex value of the string... If this is the right interpretation, you need to split the string in pairs of chars and then convert each one to the equivalent integer. Here is my code ... It writes out to stdout, but you can modify it easily in order to write to file instead to the screen.

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
using namespace std;

int main () {
        string str = "e101";
        string two_char;
        unsigned char byte;

        for (int i=0 ; i<str.size(); i+=2) {
                two_char = str.substr(i,2);
                byte = strtol(two_char.c_str(),0,16);
                cout << two_char << " " << (int)byte <<"\n";
        }
}
0

In answer to your original question about writing 2-bytes out in binary to a file in C++, you have a basic 2-step process. (1) convert your string representation of the number to a numeric value using stoi with base 16. This provides a numeric values you can store in an unsigned short. (2) write that value out to your file with f.write, not frwite where f is your open stream reference.

If you want to format the output in hex for cout, then you must set the flags for cout to output numeric values in hex-format (though not directly part of your question, it ties in the stream I/O formatting if desired.)

So essentially you have your string and convert it to a number, e.g.

    std::string str = "e101";
    unsigned short u = stoi(str, 0, 16);

Now u holds a numeric value converted from the text in str using base-16 that you can simply write to your file as a 2-byte value, e.g.

    std::string filename = "out.bin";   /* output filename */
    ...
    std::ofstream f (filename, f.trunc | f.binary); /* open out in binary */
    if (!f.write(reinterpret_cast<char*>(&u), sizeof u)) {  /* write 2 bytes */
        std::cerr << "error: write of short to file failed.\n";
        return 1;
    }

Putting it altogether, you could do something short that outputs the hex value being written with cout as well as writing it to the file "out.bin", e.g.

#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>

int main (void) {

    std::string filename = "out.bin";   /* output filename */
    std::string str = "e101";
    unsigned short u = stoi(str, 0, 16);
    /* output converted value to terminal in hex */
    std::cout.setf(std::ios::hex, std::ios::basefield);  /* set hex output */
    std::cout << "writing value to file: " << u << '\n'; /* for cout */
    /* output converted value to file */
    std::ofstream f (filename, f.trunc | f.binary); /* open out in binary */
    if (!f.write(reinterpret_cast<char*>(&u), sizeof u)) {  /* write 2 bytes */
        std::cerr << "error: write of short to file failed.\n";
        return 1;
    }
}

Example Use/Output

$ ./bin/stoi_short
writing value to file: e101

Resulting Output File

Confirm by dumping the contents of the file with a hexdump program, e.g.

$ hexdump out.bin
0000000 e101
0000002

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85