4

I have a method which writes a binary file from an int array. (it could be wrong too)

void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size)
{
    fstream binaryIo;
    binaryIo.open("PridePrejudice.bin", ios::out| ios::binary | ios::trunc);
    binaryIo.seekp(0);
    binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
    binaryIo.seekp(0);

    binaryIo.close();
}

I need to now read that binary file back. And preferably have it read it back into another array of unsigned ints without any information loss.

I have something like the following code, but I have no idea on how reading binary files really works, and no idea how to read it into an array of ints.

void bcdEncoder::readBinaryFile(string fileName)
{
    // myArray = my dnynamic int array

    fstream binaryIo;
    binaryIo.open(fileName, ios::in | ios::binary | ios::trunc);

    binaryIo.seekp(0);

    binaryIo.seekg(0);
    binaryIo.read((int*)myArray, size * sizeof(myFile));

    binaryIo.close();
}

Question:

How to complete the implementation of the function that reads binary files?

2
  • consider writing the size of the array first. It would greatly simplify the read code. Commented Sep 24, 2015 at 0:53
  • To add a note here, I cannot use vector. I have a separate class that creates dynamic arrays for me with a given size passed to it, and that class is working properly. I can also determine the size based on the information I send to these arrays. Commented Sep 24, 2015 at 16:53

4 Answers 4

4

If you're using C++, use the nice std library.

vector<unsigned int> bcdEncoder::readBinaryFile(string fileName)
{
    vector<unsigned int> ret; //std::list may be preferable for large files
    ifstream in{ fileName };
    unsigned int current;
    while (in.good()) {
        in >> current;
        ret.emplace_back(current);
    }
    return ret;
 }

Writing is just as simple (for this we'll accept an int[] but an std library would be preferable):

void bcdEncoder::writeBinaryFile(string fileName, unsigned int arr[], size_t len)
{
    ofstream f { fileName };
    for (size_t i = 0; i < len; i++)
        f << arr[i];
}

Here's the same thing but with an std::vector

void bcdEncoder::writeBinaryFile(string fileName, vector<unsigned int> arr)
{
    ofstream f { fileName };
    for (auto&& i : arr)
        f << i;
}
Sign up to request clarification or add additional context in comments.

3 Comments

I can't figure out a way to implement a similar read method without vectors, which I am not able to use in this project.
Are you completely and utterly banned from using a vector, or you're just required to return an int[]?
part of the project goal was to apply previously made custom dynamic array class file to a new project.
2

Modern alternative using std::array

Here's a code snippet that uses more modern C++ to read a binary file into an std::array.


    const int arraySize = 9216; // Hard-coded

    std::array<uint8_t, arraySize> fileArray;

    std::ifstream binaryFile("<my-binary-file>", std::ios::in | std::ios::binary);

    if (binaryFile.is_open()) {
        binaryFile.read(reinterpret_cast<char*>(fileArray.data()), arraySize);
    }

Because you're using an std::array you'll need to know the exact size of the file during compile-time. If you don't know the size of the file ahead of time (or rather, you'll need to know that the file has at least X bytes available), use a std::vector and look at this example here: https://stackoverflow.com/a/36661779/1576548

Comments

1

To simplify read operation consider storing size (i.e the number of elements in the array) before the data:

void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size)
{
   fstream binaryIo;
   binaryIo.open("PridePrejudice.bin", ios::out| ios::binary | ios::trunc);
   binaryIo.seekp(0);
   binaryIo.write(&size, sizeof(size));
   binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
   binaryIo.close();
}

The read would look something like:

void bcdEncoder::readBinaryFile(string fileName)
{
    std::vector<unsigned int> myData;
    int size;

    fstream binaryIo;
    binaryIo.open(fileName, ios::in | ios::binary | ios::trunc);

    binaryIo.read(&size, sizeof(size)); // read the number of elements 

    myData.resize(size); // allocate memory for an array 
    binaryIo.read(myData.data(), size * sizeof(myData.value_type));
    binaryIo.close();

   // todo: do something with myData
}

1 Comment

I'm guessing now that my write is just completely wrong. First off, the &size in the write fails because it says its expecting a char, but overall, when i take in my packedBcd Array (which I know has the correct values in it) the values are not being written into the .bin file in any way that I understand, if at all.
0

Thanks for the tips guys, looks like I worked it out!! A major part of my problem was that half the arguments and syntax I added to the methods were not required, and actually messed things up. Here are my working methods.

void bcdEncoder::writeBinaryFile(unsigned int packedBcdArray[], int size, string fileName)
{
    ofstream binaryIo;
    binaryIo.open(fileName.substr(0, fileName.length() - 4) + ".bin", ios::binary);
    if (binaryIo.is_open()) {
        binaryIo.write((char*)packedBcdArray, size * sizeof(packedBcdArray[0]));
        binaryIo.close();

        // Send binary file to reader
        readBinaryFile(fileName.substr(0, fileName.length() - 4) + ".bin", size);
    }
    else
        cout << "Error writing bin file..." << endl;
}

And the read:

void bcdEncoder::readBinaryFile(string fileName, int size)
{
    AllocateArray packedData(size);
    unsigned int *packedArray = packedData.createIntArray();

    ifstream binaryIo;
    binaryIo.open(fileName, ios::binary);
    if (binaryIo.is_open()) {
        binaryIo.read((char*)packedArray, size * sizeof(packedArray[0]));
        binaryIo.close();

        decodeBCD(packedArray, size * 5, fileName);
    }
    else
        cout << "Error reading bin file..." << endl;
}

With the AllocateArray being my class that creates dynamic arrays without vectors somewhat safely with destructors included.

Comments

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.