Астрономически обекти
Здравейте, опитвам да реша задачата за астрономическите обекти, но срещам някои затруднения. Ще съм благодарен, ако споделите мнения относно подхода, чрез който съм тръгнал да я решавам, и посочените затруднения.
Тъй като задачата е малко по-свободна от към това какви функционалности да има, моят подход е да има главен цикъл, който да подканва потребителя какво действие иска да предприеме - създаване на нов запис, промяна на съществуващ или намиране на съществуващ такъв. За целта има един цикъл 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;
}