@EgaNator
Учусь на программиста

Не получается реализовать в классе записи и чтения в/из файла. Какие действия посоветуете?

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

Файл Sport.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <fstream>

using namespace std;
typedef string str;

class Sport
{
private:
	str Name;
	char Team;
	float Bal;
	int Mesto;
	vector<Sport> SP;
public:
	Sport();
	Sport(str name, char team, float bal, int mesto, vector<Sport> sp);
	void setName(const str&);
	void setTeam(char);
	void setBal(float);
	void setMesto(int);

	const str& getName() const;
	const char getTeam() const;
    const float getBal() const;
	const int getMesto() const;

	void Menu();
	void Show();
	void Add();
	void Del();
	void Remove();
	
	~Sport();
};


файл Sport.cpp
#include "Sport.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>

using namespace std;


Sport::Sport()
{
	Name = "Имя не указано";
	Team = '\0';
	Bal = 0.0;
	Mesto = 0;
}

Sport::~Sport()
{
}

Sport::Sport(str name, char team, float bal, int mesto, vector<Sport> sp)
	: Name(name), Team(team), Bal(bal), Mesto(mesto), SP(sp)
{ }

void Sport::setName(const str& name)
{
	Name = name;
}

void Sport::setTeam(char team)
{
	Team = team;
}

void Sport::setBal(float bal)
{
	Bal = bal;
}

void Sport::setMesto(int mesto)
{
	Mesto = mesto;
}

const str& Sport::getName() const
{
	return Name;
}

const char Sport::getTeam() const
{
	return Team;
}

const float Sport::getBal() const
{
	return Bal;
}

const int Sport::getMesto() const
{
	return Mesto;
}

void Sport::Menu()
{
	cout << "1 - Добавить нового участника\n";
	cout << "2 - Редактировать данные об участнике\n";
	cout << "3 - Удалить участника\n";
	cout << "0 - Выход\n";
}

void Sport::Show()
{
	system("cls");
	cout << "------------------------------------------------------------------------------------------------" << endl;
	cout << "Ведомость спортивних состязаний" << endl;
	cout << "------------------------------------------------------------------------------------------------" << endl;
	cout << "  №" << setw(26) << "Фамилия участника" << setw(20) << "Код команды" << setw(25) << "Количество балов" << setw(20) << "Место в итоге" << endl;
	cout << "------------------------------------------------------------------------------------------------" << endl;
	for (int i = 0; i < SP.size(); i++) {
		cout << "  " << i + 1 << '\t' << setw(15) << SP[i].Name << setw(20) << SP[i].Team << setw(24) << SP[i].Bal << setw(20) << SP[i].Mesto << endl;
		if (i != SP.size() - 1)
		{
			cout << " -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - " << endl;
		}
	}
	cout << "------------------------------------------------------------------------------------------------" << endl;
	cout << " Примечание: D - Динамо, C - Спартак, S - Шахтер" << endl;
	cout << "------------------------------------------------------------------------------------------------" << endl;
}
void Sport::Add()
{
	int n;
	Sport t;
	SP.push_back(t);
	cout << "Введите фамилию участника: ";
	cin >> SP[SP.size() - 1].Name;
	do {
		n = 0;
		cout << "Введите код команды (D - Динамо, C - Спартак, S - Шахтер):";
		cin >> SP[SP.size() - 1].Team;
		if (SP[SP.size() - 1].Team != 'D' && SP[SP.size() - 1].Team != 'C' && SP[SP.size() - 1].Team != 'S')
		{
			n = 1;
			cout << "Вы ввели некорректный код команды, повторите ввод:\n";
		}
	} while (n == 1);
	n = 0;
	do {
		n = 0;
		cout << "Введите количество балов: ";
		cin >> SP[SP.size() - 1].Bal;

		if (!cin.good() || SP[SP.size() - 1].Bal < 0)
		{
			n = 1;
			cout << "Вы ввели некорректное число, повторите ввод:\n";
		}
	} while (n == 1);
	n = 0;
	do {
		n = 0;
		cout << "Введите итоговое место: ";
		cin >> SP[SP.size() - 1].Mesto;
		if (SP[SP.size() - 1].Mesto < 0)
		{
			n = 1;
			cout << "Вы ввели некорректное число, повторите ввод:\n";
		}
	} while (n == 1);
	n = 0;
	Show();
}
void Sport::Del()
{
	int n;
	cout << "Введите номер строки, которую Вы желаете удалить: ";
	cin >> n;
	SP.erase(SP.begin() + n - 1);
	Show();
}
void Sport::Remove()
{
	int p;
	int n;
	cout << "Введите номер строки, которую Вы хотите отредактировать: ";
	cin >> n;
	cout << "Введите фамилию участника: ";
	cin >> SP[n - 1].Name;
	do {
		p = 0;
		cout << "Введите код команды (D - Динамо, C - Спартак, S - Шахтер)::";
		cin >> SP[SP.size() - 1].Team;
		if (SP[SP.size() - 1].Team != 'D' && SP[SP.size() - 1].Team != 'C' && SP[SP.size() - 1].Team != 'S') {
			n = 1;
			cout << "Вы ввели некорректный код команды, повторите ввод:\n";
		}
	} while (p == 1);
	p = 0;
	do {
		p = 0;
		cout << "Введите количество балов: ";
		cin >> SP[SP.size() - 1].Bal;
		if (SP[SP.size() - 1].Bal < 0)
		{
			p = 1;
			cout << "Вы ввели некорректное число, повторите ввод:\n";
		}
	} while (p == 1);
	p = 0;
	do {
		p = 0;
		cout << "Введите итоговое место: ";
		cin >> SP[SP.size() - 1].Mesto;
		if (SP[SP.size() - 1].Mesto < 0)
		{
			p = 1;
			cout << "Вы ввели некорректное число, повторите ввод:\n";
		}
	} while (p == 1);
	p = 0;
	Show();
}


Файл main.cpp
#include "Sport.h"
#include <iostream>
#include <conio.h>
#include <string>
#include <vector>

using namespace std;


int main() {
	setlocale(LC_ALL, "Russian");
	int c;
	Sport B;

	do {
		B.Menu();
		cout << "Ваш выбор: ";
		cin >> c;
		switch (c) {
		case 1:
			B.Add();
			break;
		case 2:
			B.Remove();
			break;
		case 3:
			B.Del();
			break;
		case 0:
			break;
		default: cout << "Некорректный вариант выбора!" << endl;
		}
	} while (c != 0);

	_getch();
	return 0;
}
  • Вопрос задан
  • 88 просмотров
Решения вопроса 1
myjcom
@myjcom Куратор тега C++
Тыц
#include <iostream>
#include <string>
#include <vector>
#include <fstream>

using std::ofstream;
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;

class Sport
{
  vector<Sport> Sp;
  char     team;
  double   bal;
  unsigned mesto;
  string   name;
public:
  Sport(string   _name  = {}, char _team = {}, double _bal = {},
        unsigned _mesto = {}, vector<Sport> sp = {})
      : name {_name}, team{_team}, bal{_bal},
        mesto{_mesto},  Sp{sp} {}

private:
  friend ofstream& operator<<(ofstream& ofs, Sport& sp);
};

ofstream& operator<<(ofstream& ofs, Sport& sp)
{
  ofs << sp.name  << ' ';
  ofs << sp.team  << ' ';
  ofs << sp.mesto << ' ';
  ofs << sp.bal   << ' ';
  ofs << endl;
  for(auto& p : sp.Sp)
  {
    ofs << p;
  }
  return ofs;
}

void writeSportsTo(const char* filename, Sport& sp)
{
  ofstream of(filename);
  if(of)
  {
    of << sp;
    of.close();
  }
}

int main()
{
    constexpr char* filename = "C:\\sports.txt";
    Sport sp;
    writeSportsTo(filename, sp);
    return 0;
}


Чтение аналогично.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Free_ze
Пишу комментарии в комментарии, а не в ответы
Так, как вы написали в комментариях - не прокатит для сложных объектов, вроде Sport.

Во-первых, вы записываете и читаете txt-файл в двоичном формате. Вы представляете вообще, как должен выглядеть файл, содержащий данные вашего типа?

Во-вторых, у вас внутри объекта есть динамические члены (способные изменять свои размеры) - vector и string. Благодаря этому объект имеет многомерное представление в памяти и вам необходимо придумать, как спроецировать его на "плоскую" память, записать его почленно. Если с char, int, float все очевидно (их размеры известены на этапе компиляции: sizeof(char), sizeof(int), sizeof(float)), то для string, например, нужно сначала сохранить его размер (чтобы потом знать, сколько читать из файла), а потом записать содержимое. С vector - аналогично, за тем исключением, что это тот же Sport и вам нужно вызвать функцию сохранения для каждого ребенка текущего объекта (и для их детей, т.е. рекуррентно обойти дерево владения).

Чтение производить в обратном порядке.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы