0

I have an assignment that wants plain text data to be read in from a file, and then outputted to a separate binary file. With that being said, I expect to see that the contents of the binary file not to be intelligible for human reading. However, when I open the binary file the contents are still appearing as plain text. I am setting the mode like this _file.open(OUTFILE, std::ios::binary). I can't seem to figure out what I'm missing. I've followed other examples with different methods of implementation, but there's obviously something I'm missing.

For the purpose of posting, I created a slimmed down test case to demonstrate what I'm attempting.

Thanks in advance, help is greatly appreciated!

Input File: test.txt

Hello World

main.cpp

#include <iostream>
#include <fstream>

using namespace std;

#define INFILE "test.txt"
#define OUTFILE "binary-output.dat"


int main(int argc, char* argv[]) {

    char* text = nullptr;
    int nbytes = 0;
    // open text file
    fstream input(INFILE, std::ios::in);
    if (!input) {
        throw "\n***Failed to open file " + string(INFILE) + " ***\n";
    }

    // copy from file into memory
    input.seekg(0, std::ios::end);
    nbytes = (int)input.tellg() + 1;

    text = new char[nbytes];

    input.seekg(ios::beg);
    int i = 0;
    input >> noskipws;
    while (input.good()) {
        input >> text[i++];
    }
    text[nbytes - 1] = '\0';
    cout << "\n" << nbytes - 1 << " bytes copied from file " << INFILE << " into memory (null byte added)\n";

    if (!text) {
        throw "\n***No data stored***\n";
    } else {
        // open binary file for writing
        ofstream _file;
        _file.open(OUTFILE, std::ios::binary);

        if (!_file.is_open()) {
            throw "\n***Failed to open file***\n";
        } else {
            // write data into the binary file and close the file
            for (size_t i = 0U; i <= strlen(text); ++i) {
                _file << text[i];
            }

            _file.close();
        }
    }
}
P-DoxQuad
  • 3
  • 3
  • The `operator<<()` always renders text, no matter if you open the file in binary mode. Use `write()` instead. – πάντα ῥεῖ Nov 23 '21 at 18:46
  • 4
    If you're writing text to a file opened as binary file, the only difference is that the line breaks are not converted to the OS dependent ones, but kept as they are in the parameter to the write operation. – fabian Nov 23 '21 at 18:46
  • 1
    Opening a file fro writing in binary mode doesn't mean the file is going to look like garbage. An 'A' will still look like an 'A' no matter how you write it. – ichramm Nov 23 '21 at 18:47
  • _"I expect to see that the contents of the binary file not to be intelligible for human reading"_ Why do you expect that? You are writing readable text to the file. "Binary" does not mean "unintelligible". – Drew Dormann Nov 23 '21 at 18:48

2 Answers2

0

As stated here, std::ios::binary isn't actually going to write binary for you. Basically, it's the same as std::ios::out except things like \n aren't converted to line breaks.

You can convert text to binary by using <bitset>, like this:

#include <iostream>
#include <vector>
#include <bitset>

int main() {
    std::string str = "String in plain text";
    std::vector<std::bitset<8>> binary; // A vector of binaries

    for (unsigned long i = 0; i < str.length(); ++i) {
        std::bitset<8> bs4(str[i]);
        binary.push_back(bs4);
    }

    return 0;
}

And then write to your file.

CyanCoding
  • 1,012
  • 1
  • 12
  • 35
  • 2
    Re: "`std::ios::binary` isn't actually going to write binary for you" -- that depends on what you mean by "write binary". C++ streams certainly do "write binary" when you tell them to do so: the stream doesn't change any of the data that's being transferred. – Pete Becker Nov 23 '21 at 19:10
  • `You can convert text to binary by using ` this is strange statement. How this helps? Now how this translates to saving data to a file? Storing data in file is main part of the question and this answer ignores that (and most probably this would reveal how bad this answer is). – Marek R Nov 24 '21 at 11:52
0

In simplest terms, the flag std::ios::binary means:

Do not make any adjustments to my output to aid in readability or conformance to operating system standards. Write exactly what I send.

In your case, you are writing readable text and the file contains exactly what you sent.

You could also write bytes that are unintelligible when viewed as text. In that case, your file would be unintelligible when viewed as text.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180