Професионална програма
Loading...
damyan94 avatar damyan94 3 Точки

Астрономически обекти

Здравейте, опитвам да реша задачата за астрономическите обекти, но срещам някои затруднения. Ще съм благодарен, ако споделите мнения относно подхода, чрез който съм тръгнал да я решавам, и посочените затруднения.

 

Тъй като задачата е малко по-свободна от към това какви функционалности да има, моят подход е да има главен цикъл, който да подканва потребителя какво действие иска да предприеме - създаване на нов запис, промяна на съществуващ или намиране на съществуващ такъв. За целта има един цикъл while със switch конструкция.

 

Затрудненията, които имам засега са следните:

 

    1. Въпреки, че още не съм работил по тази част, подходящ ли е типът изброим за описание на вида обект? Мисля си, че е най-подходящо той да е деклариран глобално, а в класа да има обект от тип ObjType, на който да присвояваме някоя от допустимите стойности. Може ли да имаме обект от тип изброим като аргумент на конструкторите и как може да стане това, понеже за пръв път се сблъсквам с такъв случай, а информацията в интернет, която намирам, не е особено полезна?

 

    2. В case 1 на главната програма искам потребителят да въведе всички задължителни данни за новия обект и ако реши, да въведе и nickname. По този начин написан кодът, програмата винаги очаква въвеждане и на nickname. Как може да се направи така, че ако потребителят напише нов ред на конзолата, въвеждането да спре?

 

    3. В case 3 на главната програма уместно ли е прочитането на данните в паметта директно с главния поток fin >> и как може да се оптимизира така, че да спира да прочита данни в текущия обект, когато достигнем край на реда във файла (предполагам, че това не е толкова сложно, но нещо ми убягва)?

 

    4. В case 3 на главната програма при прочитането на критерии за търсене има същия проблем, както е описано в т. 2 - как при въвеждане на нов ред програмата да спре изпълнението на оператор cin >>?

 

Предварително благодаря за съдействието. Ето го и кодът, който имам до момента:

 

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

enum ObjType { star, rocky_planet, gas_giant, unknown };
ofstream fout;
ifstream fin;

//class declaration
class AstronomicalObject
{
private:
	string _solarSystem, _nickname;
	int _position;
	float _mass, _radius;
	ObjType _objType;

public:
	AstronomicalObject(string, /*ObjType,*/ int, float, float);
	AstronomicalObject(string, /*ObjType,*/ int, float, float, string);
	void renameObject(string newName) { _nickname = newName; }
	void printObject();
	void writeObject();
	string getSolarSystem() { return _solarSystem; }
	int getPosition() { return _position; }

};

//constructors
AstronomicalObject::AstronomicalObject(string solarSystem, int position, float mass, float radius)
{
	_solarSystem = solarSystem;
	_position = position;
	_mass = mass;
	_radius = radius;
}

AstronomicalObject::AstronomicalObject(string solarSystem, int position, float mass, float radius, string nickname)
{
	_solarSystem = solarSystem;
	_position = position;
	_mass = mass;
	_radius = radius;
	_nickname = nickname;
}

void AstronomicalObject::printObject()
{
	cout << _solarSystem << '-' << _position << " (" << _nickname << ") " << "{mass: " << _mass << ", radius: " << _radius << "}" << endl;
}

//write to file with separator ' '
void AstronomicalObject::writeObject()
{
	fout.open("objects.txt", ios::app);
	if(fout.is_open())
		fout << _solarSystem << ' ' << _position << ' ' << _mass << ' ' << _radius << ' ' << _nickname << endl;
	fout.close();
}

int main()
{
	vector<AstronomicalObject> objects;
	string solarSystem, nickname, searchSolarSystem;
	int position, searchPosition = 0;
	float mass, radius;
	int objType, numObjects = 0, action;
	bool ok = 0;

//main program loop
	while (1)
	{
		cout << "---------------------------------------------\n";
		cout << "Please choose action:\n\n";
		cout << "1. Input new object\n2. Change name of existing object\n3. Print info for existing object\n4. Exit program\n";
		cin >> action;

		switch (action)
		{
		case 1: //input new object
			do
			{
				cout << "Please enter on the same line: solar system, position, mass, radius, nickname(optional)\n";
				cin >> solarSystem >> position >> mass >> radius >> nickname;
				if (nickname == "")
					objects.emplace_back(solarSystem, position, mass, radius);
				else
					objects.emplace_back(solarSystem, position, mass, radius, nickname);
				objects[numObjects].writeObject();
				numObjects++;
			} while (cin.get() != '\n');
			objects.clear();

			break;

		case 2: //change name of object - not started yet
			objects.clear();

			break;

		case 3: //lookup object from file
			
			//open file and read objects to memory
			fin.open("objects.txt", ios::in);
			while (fin.eof())
			{
				fin >> solarSystem >> position >> mass >> radius >> nickname;
				if (nickname == "")
					objects.emplace_back(solarSystem, position, mass, radius);
				else
					objects.emplace_back(solarSystem, position, mass, radius, nickname);
			}
			
			//enter search criteria
			cout << "Please enter on the same line name of solar system and object position(optional)\n";
			do
			{
				cin >> searchSolarSystem >> searchPosition;
			} while (cin.get() != '\n');

			ok = 0;

			//find all objects in given solar system
			if (searchPosition == 0)
			{
				for (int i = 0; i < objects.size(); i++)
					if (objects[i].getSolarSystem() == searchSolarSystem)
					{
						objects[i].printObject();
						ok = 1;
					}
				if (ok == 0)
					cout << "No such solar system exists\n";
				ok = 0;
			}
			
			//find specific object in given solar system
			else
			{
				for (int i = 0; i < objects.size(); i++)
					if (objects[i].getSolarSystem() == searchSolarSystem && objects[i].getPosition())
					{
						objects[i].printObject();
						ok = 1;
					}
				if (ok == 0)
					cout << "No such solar system or object in position exists\n";
				ok = 0;
			}
			fin.close();
			objects.clear();

			break;

		case 4: //exit program
			return 0;
		}
	}
	
	return 0;
}

 

Тагове:
1
C++ OOP 25/07/2021 17:02:31
damyan94 avatar damyan94 3 Точки

Много благодаря за помощта, сега задачата е може би на 80 % решена - имаме функционалност за запис, промяна и търсене на обекти. Успях да внедря някои от предложенията, за останалите ще ми трябва малко повече време и да си припомня материала за напреднали. Ето кодът до момента и текстов файл със случайно генерирани обекти:

 

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

enum OBJECT_TYPE { STAR, ROCKY_PLANET, GAS_GIANT, UNKNOWN };
enum APP_MENU_OPTIONS {EXIT_APP, ADD_OBJECTS, CHANGE_OBJECT, LOOKUP_OBJECTS };
std::ofstream fout;
std::ifstream fin;

class AstronomicalObject
{
private:
	std::string _solarSystem, _nickname;
	int _position;
	float _mass, _radius;
	OBJECT_TYPE _objType = UNKNOWN;

public:
	AstronomicalObject(std::string&, int, float, float, std::string&);
	void renameObject(std::string newName) { _nickname = newName; }
	void printObject();
	void writeObject();
	std::string getSolarSystem() { return _solarSystem; }
	int getPosition() { return _position; }
};

AstronomicalObject::AstronomicalObject(std::string& solarSystem, int position, float mass, float radius, std::string& nickname)
{
	_solarSystem = solarSystem;
	_position = position;
	if (_position == 1)
		_objType = STAR;
	_mass = mass;
	_radius = radius;
	_nickname = nickname;
}

void AstronomicalObject::printObject()
{
	std::cout << _solarSystem << "-" << _position << " (" << _nickname << ") " << "{mass: " << _mass << ", radius: " << _radius << "} ";
	switch (_objType)
	{
	case STAR:
		std::cout << "STAR" << std::endl;
		break;
	case ROCKY_PLANET:
		std::cout << "ROCKY PLANET" << std::endl;
		break;
	case GAS_GIANT:
		std::cout << "GAS GIANT" << std::endl;
		break;
	case UNKNOWN:
		std::cout << "UNKNOWN" << std::endl;
		break;
	}
}

void AstronomicalObject::writeObject()
{
	fout << _solarSystem << ' ' << _position << ' ' << _mass << ' ' << _radius << ' ' << _nickname << std::endl;
}

int main()
{
	std::vector<AstronomicalObject> objects;
	std::string solarSystem, nickname, searchSolarSystem, inputLine;
	int action, position, searchPosition = 0;
	float mass, radius;
	bool ok = 0;
	std::istringstream ss(inputLine);
	ss.clear();

	//read from file to vector of objects in memory
	fin.open("objects.txt", std::ios::in);
	while (!fin.eof())
	{
		//read a line from the file to a string inputLine and read from inputLine to variables
		getline(fin, inputLine, '\n');
		if (inputLine == "")
			continue;
		ss.str(inputLine);
		ss >> solarSystem >> position >> mass >> radius >> nickname;
		ss.clear();

		//create new object at the back of the vector and write the data in it
		objects.emplace_back(solarSystem, position, mass, radius, nickname);
		nickname = "";
	}
	fin.close();

	while (1)
	{
		std::cout << "--------------------------------------------------\n";
		std::cout << "Please choose action:\n\n";
		std::cout << "0. Exit program\n1. Input new objects\n2. Change name of existing object\n3. Print info for existing objects\n";
		std::cin >> action;
		std::cin.ignore();

		switch (action)
		{
		case EXIT_APP:
			//clear the contents of the txt file and write the new data from memory to it
			fout.open("objects.txt");
			if (fout.is_open())
				for (int i = 0; i < objects.size(); i++)
				{
					objects[i].writeObject();
				}
			fout.close();
			objects.clear();
			return 0;

		case ADD_OBJECTS:
			//write to file until the user has input 0
			std::cout << "\nPlease enter on the same line: solar system, position, mass, radius, nickname(optional)\nEnter 0 to stop entering objects\n";
			while (1)
			{
				//read a line from cin that the user has input in inputLine and read from the inputLine to variables in memory, exit loop on 0
				getline(std::cin, inputLine, '\n');
				if (inputLine == "0")
					break;
				if (inputLine == "")
					continue;
				ss.str(inputLine);
				ss >> solarSystem >> position >> mass >> radius >> nickname;
				ss.clear();

				//create new object at the back of the vector
				objects.emplace_back(solarSystem, position, mass, radius, nickname);
				nickname = "";
			}
			break;

		case CHANGE_OBJECT:
			//read a line from cin that the user has input in inputLine and read from the inputLine to variables in memory
			std::cout << "Please enter on the same line name of solar system and object position\n";
			getline(std::cin, inputLine, '\n');
			ss.str(inputLine);
			ss >> searchSolarSystem >> searchPosition;
			ss.clear();

			//rename every object in memory that satisfies the search conditions with the new name provided by the user
			std::cout << "Please enter new name for the object\n";
			getline(std::cin, inputLine, '\n');
			for (int i = 0; i < objects.size(); i++)
				if (objects[i].getSolarSystem() == searchSolarSystem && objects[i].getPosition() == searchPosition)
				{
					objects[i].renameObject(inputLine);
					ok = 1;
				}
			searchPosition = 0;
			if (ok == 0)
				std::cout << "No such solar system or object in position exists\n";
			ok = 0;
			break;

		case LOOKUP_OBJECTS:
			//read variables from cin that the user has input
			std::cout << "Please enter on the same line name of solar system and object position(optional)\n";
			std::cin >> searchSolarSystem;
			if (std::cin.peek() != '\n')
				std::cin >> searchPosition;

			//based on user input show the objects that satisfy the search conditions
			ok = 0;
			std::cout << "--------------------------------------------------" << std::endl;

			//if the user has input only solar system name, show everything in the system
			if (searchPosition == 0)
			{
				for (int i = 0; i < objects.size(); i++)
					if (objects[i].getSolarSystem() == searchSolarSystem)
					{
						objects[i].printObject();
						ok = 1;
					}
				if (ok == 0)
					std::cout << "No such solar system exists\n";
				ok = 0;
			}

			//if the user has input solar system name and position, only show the required object
			else
			{
				for (int i = 0; i < objects.size(); i++)
					if (objects[i].getSolarSystem() == searchSolarSystem && objects[i].getPosition() == searchPosition)
					{
						objects[i].printObject();
						ok = 1;
					}
				searchPosition = 0;
				if (ok == 0)
					std::cout << "No such solar system or object in position exists\n";
				ok = 0;
			}
			break;
		}
	}

	return 0;
}

 

0