Считать структуры данных, записанные в бинарный файл и обработать

Рейтинг: 0Ответов: 1Опубликовано: 08.04.2023

При считывание данных из файлов, считывается только одна и таже структура, которую я добавляю в конце, хотя я записываю несколько или их нужно при записывание разделять например переходом на другую строчку.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

struct Info{
    char Surname[20];
    char Name[1];
    char Patronymic[1];
    char group[5];
    int grade[3];
};

void setInfo(Info& info){
    ofstream fout("Wedomost.dat", ostream::binary | ostream::app);                
    cout << "Surname: "; cin >> info.Surname ;
    cout << "Name: "; cin >> info.Name;
    cout << "Patronymic: "; cin >> info.Patronymic;
    cout << "Group: "; cin >> info.group;
    cout << "Grade: "; cin >> info.grade[0]; cin >> info.grade[1]; cin >> info.grade[2];
    fout.write((char*)&info, sizeof(Info));   
    fout.close();                               
}

void getInfo(Info& info){
    ifstream fin("Wedomost.dat", ios::in);
    while (!fin.eof())
    {
        fin.read((char*)&info, sizeof(Info));
    }
    fin.close();
}

int main(){
    cout << "===START===" << endl;
    string path = "Wedomost.dat";
    ofstream fout(path, ios::binary);
    ifstream fin(path, ios::binary);
    bool flag1 = true;
    int n;
    int count = 0;
    while(flag1){
        cout << "press (1) - add data or new file, press (2) - work with file, Press (0) - end work with file"<< endl;
        cin >> n;
        if (n == 1){
            int b;
            bool flag2 = true;
            while(flag2){
                cout <<"add data(1), new file(2), End this (0)"<<endl;
                cin >> b;
                if(b == 1){ //add data
                    int countA;
                    cout<<"Count of Students: ";
                    cin >> countA;
                    count+=countA;
                    Info*f = new Info[countA];
                    for(int i = 0; i < countA; i++){
                        setInfo(f[i]);
                    }
                    delete[] f;        
                }
                if(b == 2){ //new file
                    fout.open(path);
                    fout.close();
                }
                if(b == 0){
                    flag2 = false;
                }
            }
        }
        if(n == 2){// work with file
            int dvoishnik = 0;
            cout << "---dvoishnik scanner has started its work---" << endl;
            Info*tmp = new Info[count];
            ifstream fin("Wedomost.dat", ios::in);
            for(int i = 0; i < count; i++){  
                getInfo(tmp[i]); 
                if (tmp[i].grade[0] == 2 || tmp[i].grade[1] == 2 || tmp[i].grade[2] == 2 ){
                    cout<<"FIO: "<<tmp[i].Surname<<" "<<tmp[i].Name[0]<<" "<<tmp[i].Patronymic[0]<<endl
                    <<"Group: "<<tmp[i].group<<endl<<"Grade: "<<tmp[i].grade[0]<<" "<<tmp[i].grade[1]<<" "<<tmp[i].grade[2]<<endl;
                    dvoishnik += 1;
                }
            }
              
            if (dvoishnik == 0){
                cout <<"Not found"<<endl;
            }
            fin.close;
            delete[]tmp;
            flag1 = true;
        }
        if(n == 0){
            flag1 = false;
            cout << "===END===" << endl;
        }
    }
}

Если я буду записывать структуры в каждую отдельную строчку, то смогу ли я считывать структуры построчно, если да, то как изменится fin.read((char*)&info, sizeof(Info)) Вот как я думаю она будет выглядеть, но не знаю как считывать структуру находящуюся в этой строке.

string str;
while(!fin.eof()){
    str="";
    getline(fin.str);
    *Считывание строки в массив структур*
}

Если верхнее не возможно, то как мне тогда перенести функцию как цикл в код, чтобы работало. Подскажите пожалуйста.

Ответы

▲ 0Принят

Поискав альтернативы, пришёл к такому решению

#include <iostream>
#include <fstream>
using namespace std;

struct Student
{
    string name;
    string group;
    int marks[3];
};

void writeToFile(Student arr[], int size)
{
    ofstream file("Wedomost.dat", ios::binary | ios::app);
    if (!file)
    {
        cout << "Error opening file!" << endl;
        return;
    }
    file.write((char *)arr, size * sizeof(Student));
    file.close();
}

void readFromFile()
{
    cout << "===Student(s) with '2'===" << endl;
    int count = 0;
    ifstream file("Wedomost.dat", ios::binary);
    if (!file)
    {
        cout << "Error opening file!" << endl;
        return;
    }
    Student s;
    bool found = false;
    while (file.read((char *)&s, sizeof(Student)))
    {
        for (int i = 0; i < 3; i++)
        {
            if (s.marks[i] == 2)
            {
                found = true;
                break;
            }
        }
        if (found)
        {
            count += 1;
            cout << "Name: " << s.name << endl;
            cout << "Group: " << s.group << endl;
            cout << "Marks: " << s.marks[0] << ", " << s.marks[1] << ", " << s.marks[2] << endl;
        }
        found = false;
    }
    if (!count != 0)
    {
        cout << "No students with at least one 2 found!" << endl;
    }
    file.close();
}

int main()
{
    int n1;
    bool flag1 = true;
    while (flag1)
    {
        cout << "press (1) - add data or new file, press (2) - work with file, Press (0) - end work with file" << endl;
        cin >> n1;
        if (n1 == 1)
        {
            int n2;
            bool flag2 = true;
            while (flag2)
            {
                cout << "add data(1), new file(2), End this (0)" << endl;
                cin >> n2;
                if (n2 == 1)
                {
                    int size;
                    cout << "Enter number of students: ";
                    cin >> size;
                    Student *arr = new Student[size];
                    for (int i = 0; i < size; i++)
                    {
                        cout << "Enter name: ";
                        cin >> arr[i].name;
                        cout << "Enter group: ";
                        cin >> arr[i].group;
                        cout << "Enter marks (3): ";
                        for (int j = 0; j < 3; j++)
                        {
                            cin >> arr[i].marks[j];
                        }
                    }
                    writeToFile(arr, size);
                }
                if (n2 == 2)
                {
                    ofstream fout("Wedomost.dat", ios::binary);
                    fout.open("Wedomost.dat");
                    fout.close();
                }
                if (n2 == 0)
                {
                    flag2 = false;
                }
            }
        }
        if (n1 == 2)
        {
            readFromFile();
        }
        if (n1 == 0)
        {
            cout << "===END===" << endl;
            flag1 = false;
        }
    }
}