Home > OS >  Writing and reading data to binary file using fstream
Writing and reading data to binary file using fstream

Time:07-16

I need to create a binary file and store inside it 10 numbers, and after that go one by one element of file and replace it with it's opposite number.

#include <iostream>
#include <fstream>
int main() {
  std::fstream file("numbers.dat", std::ios::app | std::ios::in|std::ios::out|std::ios::binary);
  for (double i = 1; i <= 10; i  )
    file.write(reinterpret_cast<char*>(&i), sizeof i);
  int length_of_file = file.tellg();
  int number_of_elements = length_of_file / sizeof(double);
  for (int i = 0; i < number_of_elements; i  ) {
    double num;
    file.seekg(0); // change mode to reading
    file.seekg(i * sizeof (double));
    file.read(reinterpret_cast<char*>(&num), sizeof num);
    num = num * -1;
    file.seekp(0); // change mode to writing
    file.seekp(i * sizeof (double));
    file.write(reinterpret_cast<char*>(&num), sizeof num);
  }
  // after change
  file.seekg(0, std::ios::end); // position cursor to the end
  length_of_file = file.tellg();
  number_of_elements = length_of_file / sizeof(double);
  for (int i = 0; i < number_of_elements; i  ) {
    double num;
    file.seekg(i * sizeof (double));
    file.read(reinterpret_cast<char*>(&num), sizeof num);
    std::cout << num << " ";
  }
  return 0;
}

OUTPUT: 1 2 3 4 5 6 7 8 9 10 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10

If I don't use std::ios::app and make an empty file numbers.dat before running program, I would get correct output:

-1 -2 -3 -4 -5 -6 -7 -8 -9 -10

std::ios::app according to cpp reference means seek to the end of stream before each write

Is there any way to create a file with mode that would seek to the beginning of stream before each write?

Is there anyway to solve this without creating an empty file before running program?

  • Note: It is not allowed to load file elements into an array or similar container data structure.

CodePudding user response:

Your mode is wrong in two ways. Firstly std::ios::app | std::ios::binary does not allow you to read from the file, and secondly it means that all writes will be at the end of the file irrespective of the current position.

The -1 file position that you see means the seekg call has failed, presumably because you tried to read from a file you hadn't opened with std::ios::in.

You should use std::ios::in | std::ios::out | std::ios::binary although this requires the file to exist before you open it, or you could use std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary but this will destroy any existing contents of the file.

BTW the repeated seekg and seekp aren't needed. You only need to set the position one time to change modes.

  • Related