Мне нужна помощь, чтобы правильно записать поля объекта в файл последовательно - PullRequest
0 голосов
/ 13 октября 2019

Я работаю над проектом, который в основном записывает в файл содержимое данных полей некоторых объектов, которые я создал (одним из них является pers1, класса PERSON);

Я вставил данные в члены поля объекта pers1 и открыл файл, пытаясь записать содержимое этих членов поля (имя строки, фамилия и unsigned int age) в файл, используяФункция file.write. Он написал части содержимого, между много мусора. Пожалуйста, помогите мне написать правильный код, чтобы я мог последовательно записывать данные каждого человека в файл. Спасибо

   #include<iostream>
    #include<string>
    #include<fstream>
    #include <sstream>
    #include <iomanip>
    #include <list>

    class PERSON
    {
        string name;
        string surname;
        unsigned int age;
    public:
        void inputinfo()
        {
            cin>>name;
            cin>>surname;
            cin>>age;
        }
        outputinfo()
        {
            cout<<name;
            cout<<surname;
            cout<<age;
        }
    };

    class STUDENT: public PERSON
    {
        int ID;
        float marks_sum;
        string belonging_class;
    public:
        inputinfo()
        {
            cin>>name;
            cin>>surname;
            cin>>age;
            cin>>ID;
            cin>>marks_sum;
            cin>>belonging_class;
        }
    };

    void writeinfile()
    {
        PERSON pers1;
        ofstream file1
        file1.open("Students.txt", std::ofstream::out | std::ofstream::app);
        pers1.inputinfo();
        file1.write(pers1.c_str(),pers1.length()); // this is the second aproach I've found on internet, but it gives errors;
        file1.write((char*)&pers1, sizeof(pers1)); // this one is puting alot of garbage into the file, alongside fields data.
        fisier.close();
    }

    int main
    {
        int opt1, opt2;
        char option;

        switch(opt1)
        {
        case 1:
            do
            {
                cout<<endl;
                        <<"Choose one of variants"<<"1.Students"<<"2.Teachers"<<"3.Get back to main menu"<<endl;
                cin>>opt2;
                switch(opt2)
                {
                case 1:
                    do
                    {
                        cout<<"Do you wish to introduce a new student(Y/N)?";
                        cin>>option;
                        if(option!='N')
                            writeinfile()
                    } while(option!='N');
                            break;
                    default:
                        cout<<"Incorect!"<<endl;
                    }
                    while(opt2!=3);
                    break;
                case 2: "...."
                    ;
                    break
                case 3: "...."
                    ;
                    break;
                }
            }
        }

Я ожидаю чистой записи данных поля в файл каждый раз, когда вызываю вышеупомянутую функцию. Например, для 1-й итерации, когда я ввожу данные в поле объекта: имя: Джон, фамилия: Доу, возраст: 45 лет, я надеюсь увидеть эти данные в одной строке в файле (и между ними нет мусора).

1 Ответ

1 голос
/ 13 октября 2019
#include <iostream>
#include <fstream>

std::ostream& operator<< (std::ostream& os, const PERSON& value )
{
    // here, you decide how the output format should look like. See below.
    // ...
    return os;
}

std::istream& operator>> (std::istream& is, PERSON& value )
{
    // here, you do the reverse of what you chose in operator<<(). See below.
    // ...
    return is;
}

Хотя вы сможете быстро взломать реализацию этих двух функций, стоит подумать о требованиях, которые вы хотите выполнить:

  • Техническое обслуживание? Что произойдет с вашими файлами в будущем, когда вы смените ЛИЦА (например, дополнительные поля)? Вы все еще хотите использовать эти старые файлы?
  • Надежность. Придется ли вам уделять внимание локализации? Что произойдет, если ваш первый китайский студент прибудет с именем кандзи? Вам нужна кодировка utf8 или подобное? Будете ли вы сталкиваться с «пропущенными значениями»?
  • Масштабируемость? Вы закончите писать свою собственную маленькую базу данных со своим собственным SQL для последующего запроса для подмножеств людей? Сможете ли вы прочитать весь файл, если он превзойдет все ожидания? Будут ли поступать новые файлы с другими данными, и позже возникнет необходимость их связать? (ВНЕШНЕЕ СОЕДИНЕНИЕ, ВНУТРЕННЕЕ СОЕДИНЕНИЕ, ...)

Как видно из этого короткого и, конечно, неполного списка, вы находитесь на перекрестке: используйте вместо этого базу данных? Использовать стандартный формат сериализации, такой как XML или JSON, или буферы протокола, или FastNProto, или что-нибудь еще модное сегодня? Или просто идти вперед и делать свое дело, так как все это быстро и грязно?

Теперь к практическим вещам:

Внутри вашего operator<< вы можете «сбросить» ваши элементы следующим образом (придерживаясь того, что вы написали в вопросе):

os << "name: " << value.name.c_str() 
   << ", surname: " << value.surname.c_str() 
   << ", age: " << value.age 
   << std::endl;

И чтобы прочитать его обратно, вы соответственно реализуете operator>>.

std::string tag;
is >> tag; // optionally make sure it is "name:"
is >> value.name;
// ... (The commas might need some fiddling... well you wanted help not a full solution...)

Затем все, что вам нужно сделать, это проверить его, например, используя поток строк, сериализовать человека, прочитать его в другой экземпляр и сравнить. И ты должен быть готов;)

...