A
A
Andrey Zagorodniy2022-03-09 12:51:15
C++ / C#
Andrey Zagorodniy, 2022-03-09 12:51:15

How to fix a bug with line-by-line reading from a C++ binary file?

There is an input function:
void input() {
  ofstream In("AutoBase.txt", ios::binary);
  char k = '+';
  AutoBase a;
  string Read;
  while (k == '+') {
    cout << "Enter name of car: "; getline(cin, a.Name);
    cout << "Enter Release Date with a point '10.10.2010': "; getline(cin, Read);
    a = Divide(a, Read, 0);
    cout << "Enter Sale Release Date with a point '10.10.2010': "; getline(cin, Read);
    a = Divide(a, Read, 1);
    cout << "Enter '+' in case you want to contnue: "; cin >> k;
                In.write((char*)&a, sizeof(AutoBase));
    cin.ignore();
  }
  In.close();
}
AutoBase Divide(AutoBase a, string Read, bool b) {
  int pos1 = Read.find('.');
  int pos2 = Read.rfind('.');
  if (!b) {
    a.Release.day = stoi(Read.substr(0, pos1));
    a.Release.mounth = stoi(Read.substr(pos1 + 1, pos2));
    a.Release.year = stoi(Read.substr(pos2 + 1));
  }
  else {
    a.SaleRelease.day = stoi(Read.substr(0, pos1));
    a.SaleRelease.mounth = stoi(Read.substr(pos1 + 1, pos2));
    a.SaleRelease.year = stoi(Read.substr(pos2 + 1));
  }
  return a;
}


There is the structure itself:
struct Data {
  int year;
  int mounth;
  int day;
};
struct AutoBase {
  string Name;
  Data Release;
  Data SaleRelease;
};


And I'm trying to write an output function:
void output(string name) {
  ifstream Out(name, ios::binary);
  AutoBase a;
  while (Out.read((char*)&a, sizeof(AutoBase))) {
    cout << endl << a.Name << "   " << a.Release.day << "." << a.Release.mounth << "." << a.Release.year << "   " << 
                a.SaleRelease.day << "." << a.SaleRelease.mounth << "." << a.SaleRelease.year;
  }
  Out.close();
}

So: after outputting the text from the file, an error pops up
6228cb96da98c393544151.png

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
res2001, 2022-03-09
@Roman2017

  1. It would be nice to hide the code under the code tag (there is a button in the toolbar) and return the markup, it is not possible to read.
  2. The sequence of input() and output() calls is not visible.
  3. In input(), you open the file for writing, but do not write anything there, as a result, the file is empty.
  4. In output you are not reading correctly:

The bottom line is that the string type stores the string itself in dynamic memory, and not in the object itself (there is only a pointer to dynamic memory in the object). string is used by you in AutoBase.
In the way you try to read from a file, you will read some kind of pointer and most likely there will be an access to unallocated memory and the program will crash. I suspect that you would have implemented the record in the same way and a pointer would be written to the file, not a string.
You need to read and write the string object differently. There are 2 options:
  • First, we write/read the size of the string, then we write/read the string itself of the given size.
  • We write the whole line, at the end we add some kind of separator. The character '\0' can be used as a delimiter, just like in raw C strings, or whatever you like, as long as the delimiter cannot be contained in the string itself. When reading, it is necessary to read byte by byte until the delimiter character is encountered.

Which option to implement is up to you.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question