При чтении файла в C++, как он автоматически помещает символ в массив символов и числа в целочисленную переменную?

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

class akh {
public:
    char name[20];
    int age;
};

int main() {
    akh ak;
    cout << "Size of ak:" << sizeof(ak) << endl;
    fstream fout("abc.dat", ios::binary | ios::out);
    cout << "\nEnter your name: ";
    cin.getline(ak.name, 20);
    cout << "\nEnter your age: ";
    cin >> ak.age;

    fout.write((char*) &ak, sizeof(ak));
    fout.close();

    fstream fin("abc.dat", ios::in | ios::binary);
    fin.read((char*)&ak, sizeof(ak)); // automatically puts name in ak.name and age in ak.age ? How is this happening?
    cout << "\nName: " << ak.name;
    cout << "\nAge: " << ak.age;
    fin.close();

    return 0;
}
  1. Как это происходит? Также, если у меня есть "myName19" в текстовом файле и я начинаю читать, он автоматически помещает myName в char и 19 в целочисленную переменную.
  2. После закрытия файла, указатель Tellg автоматически переместится в начало файла?
  3. Есть ли другой метод для чтения и записи в двоичном файле, кроме ((char*)&x,sizeof(x))??

1 ответ

  1. Как это происходит?

Вы пишете полный макет памяти класса akh в двоичный файл как есть.
Так что, если вы прочитаете его обратно таким же образом и с тем же числом байтов, у вас будет та же схема памяти в ak пример.

  1. После закрытия файла, указатель Tellg автоматически переместится в начало файла?

Нет больше нет tellg указатель сохраняется после вашего звонка close(),

Для ввода вы открываете новый fstream пример fin, который начинает чтение с начала файла.

  1. Есть ли другой метод для чтения и записи в двоичном файле, кроме ((char*)&x,sizeof(x))??

Для бинарных файлов нет. Как упоминалось ранее, вы хотите написать и прочитать точное количество байтов, как они выложены в памяти.

Если вы хотите, чтобы в текстовом файле были удобочитаемые символы, используйте операторы форматированного текста << для вывода и >> для ввода.


Когда я запускаю ваш код, ваша проблема становится понятной. std::getline() вариант, который вы используете, занимает ровно 20 символов от ввода до ak.name:

cin.getline(ak.name, 20);

Вы можете исправить это, заменив вышеуказанную строку на

cin >> ak.name;

и введите пробел между именем и возрастом при вводе.

Вот решение, где все работает, как задумано, и показывает макет памяти вашего двоичного файла.

Другие вопросы по тегам