Помощь - Поиск - Пользователи - Календарь
Полная версия: Командный процессор
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Neonig
Здравствуйте.
В очередной раз взываю к помощи професионалов. У нас есть предмет ООП, там мы как бы разбиваемся на группы и выполняем задание, в общем такое задание один из участников реализовал, но выяснились недостатки и очевидные несоответствия с условием и все - переделать и доработать уже не можем, а сроки жмут. Далее представляю всю программу в исходнике. Задание следующее


Цитата
Реализовать программу, выполняющую ограниченный набор команд. Команды и аргументы к ним записываются в текстовом файле. Имя файла передается в аргументах командной строки. Каждая команда имеет свой набор аргументов. Если процессор не знает какую либо команду, то он выводит сообщение об ошибке и продолжает работать со следующей командой.

Необходимо реализовать следующие команды:

Название Аргументы Описание Примеры
print <строка> Распечатать на экране строку, заданную в аргументе print Hello World
eval <expression> Вычислить простую арифметическую операцию (+ , - , * , /). Результат вывести на экран. В случае некорректных аргументов вызывать исключение std::invalid_argument eval 8 / 2
createfile <file> Создать файл c именем <file>. Если файл уже существует, то пересоздать. Запросить ввод данных от пользователя (одна строка), записать введенные данные в файл. createfile test.txt
exec <command> Запустить командную строку, что записана в <command>. Используйте функцию system() из библиотеки "linesystem.h". exec notepad.exe test.txt
copy test.txt test2.txt
increment <file>
<file value> Прочитать содержимое файла <file> и проинтерпретировать его как int. Если в int не конвертируется вызывать исключение std::invalid_argument. Иначе увеличить полученное число на заданное значение и перезаписать в файл. Если число не задано, увеличить на 1. increment test.txt
increment test.txt 1
viewfile <file> Вывести содержимое файла c именем <file> на экран. Если файл не существует, вызывать исключение std::invalid_argument viewfile test.txt

Пример исходного файла для командного процессора:

print Hello
print I know 2+2=
eval 2+2
print Please input your age:
createfile age.txt
increment age.txt
print It is your age in next year:
viewfile age.txt
print You could check it
exec notepad.exe age.txt



Каждая команда представляется в виде класса, отнаследованного от абстрактного класса Command:

class Command {
private:
string args;
public:
Command(const string& s = "") : args(s){};

void setArgs(const string& s) {
args = s;
};
const string& getArgs() const {
return args;
};
friend istream& operator>>(istream& in, Command& c) {
return in >> c.args;
};
friend ostream& operator<<(ostream& out, const Command& c) {
return out << c.getName() << " " << c.args << endl;
};

virtual const string& getName() const = 0;
virtual void execute() const throw (std::invalid_argument) = 0;
};
Для инициализации и выполнения списка команд необходимо реализовать класс CommandList, который должен содержать следующие методы и операторы:
friend ostream& operator<<(ostream& out, const CommandList& c) {
// Вывести на экран все команды
// Обход списка с помощью класса std:iterator
return out;
};
friend istream& operator>>(istream& in, CommandList& c) {
// Считать из потока.
// В случае консольного ввода
// выполнение прекращается если строка равна ^D
return in;
};
void init(const string& file) {
// Считать из файла, используя оператор >>
}
void execute() const throw (std::invalid_argument) {
// Выполнить все команды.
// Обход списка с помощью класса std:iterator
}
Особенности реализации класса CommandList:
1. Файл считывается построчно с помощью класса для работы с потоками std::ifstream.
2. Команды хранятся в защищенном поле класса типа std::list
3. Обход элементов списка осуществляется с помощью итератора std::iterator

Пример использования класса CommandList:
CommandList cl = CommandList();

// Чтение из файла:
cl.init("commands.txt");
cl.execute();

// Чтение с консоли:
cin >> cl;
cout << cl;
cl.execute();


Сам код:
cmanager.h:
#pragma once
#ifndef CMANAGER_H
#define CMANAGER_H

#include <fstream>
#include "pcontainer.h"

class CManager
{
private:
PervertedContainer f_command_list;
CManager();
CManager(const CManager&);
const CManager& operator=(const CManager&);
public:
CManager(std::ifstream& fin);
~CManager();

void execute();
};

#endif //CMANAGER_H

command.h:

#pragma once
#ifndef COMMAND_H
#define COMMAND_H

#include <string>
#include "pcontainer.h"

class Command:public StorableElement
{
private:
const Command& operator=(const Command&);
public:
static Command *create(std::string name);
virtual void print()=0;
virtual void execute()=0;
virtual void init(std::string arg)=0;
};

class PrintCommand:public Command
{
private:
std::string f_arg;
PrintCommand();
PrintCommand(const PrintCommand&);
const PrintCommand& operator=(const PrintCommand&);
public:
static const std::string f_name;
static PrintCommand *create();
void print();
void execute();
void init(std::string arg);
};

class CreateCommand:public Command
{
private:
std::string f_arg;
CreateCommand();
CreateCommand(const CreateCommand&);
const CreateCommand& operator=(const CreateCommand&);
public:
static const std::string f_name;
static CreateCommand *create();
void print();
void execute();
void init(std::string arg);
};

class ExecCommand:public Command
{
private:
std::string f_arg;
ExecCommand();
ExecCommand(const ExecCommand&);
const ExecCommand& operator=(const ExecCommand&);
public:
static const std::string f_name;
static ExecCommand *create();
void print();
void execute();
void init(std::string arg);
};

class IncCommand:public Command
{
private:
std::string f_arg;
IncCommand();
IncCommand(const IncCommand&);
const IncCommand& operator=(const IncCommand&);
public:
static const std::string f_name;
static IncCommand *create();
void print();
void execute();
void init(std::string arg);
};

class DecCommand:public Command
{
private:
std::string f_arg;
DecCommand();
DecCommand(const DecCommand&);
const DecCommand& operator=(const DecCommand&);
public:
static const std::string f_name;
static DecCommand *create();
void print();
void execute();
void init(std::string arg);
};

class ViewCommand:public Command
{
private:
std::string f_arg;
ViewCommand();
ViewCommand(const ViewCommand&);
const ViewCommand& operator=(const ViewCommand&);
public:
static const std::string f_name;
static ViewCommand *create();
void print();
void execute();
void init(std::string arg);
};

#endif //COMMAND_H

container.h:
#pragma once
#ifndef CONTAINER_H
#define CONTAINER_H

#include <exception>
#include <stdexcept>

template<class _type> class Container
{
private:
class Elem
{
private:
Elem *f_prev;
Elem *f_next;
_type f_data;

Elem(const Elem& el);
const Elem& operator=(const Elem& el);
public:
Elem();
Elem(_type data,Elem *const insertbefore);
~Elem();

_type get_data()const;
_type& get_data_ref();
Elem *get_next()const;
Elem *get_prev()const;
void set_next(Elem *const next);
void set_prev(Elem *const prev);
};
Elem *f_first;
int f_count;
int f_state;

Elem f_afterlast;
public:
class Iterator
{
private:
const Container *f_parent;
Elem *f_el;
bool f_bad;
int f_state;

int get_state()const;
public:
class bad_iterator:public std::exception
{
public:
virtual const char *what()const;
};
Iterator();
Iterator(const Iterator& it);
Iterator(const Container *const cont,Elem *const el);
const Iterator& operator=(const Iterator& it);

bool is_bad()const;
const Container *get_parent()const;
Elem *get_elem()const;
bool operator==(const Iterator& it)const;
bool operator!=(const Iterator& it)const;
_type& operator*();
_type operator*()const;
const Iterator& operator++();
const Iterator operator++(int);
const Iterator& operator--();
const Iterator operator--(int);
~Iterator();
};

Container();
Container(const Container& cont);
const Container& operator=(const Container& cont);
~Container();

const Iterator begin()const;
const Iterator end()const;
void insert(_type data,const Iterator &it);
void remove(const Iterator &it);

const Elem *get_afterlast()const;
const Elem *get_first()const;
int get_state()const;
void add(_type data);
void clear();
int size()const;
_type operator[](int pos)const;
_type& operator[](int pos);
};

#include "container.hh"

#endif //CONTAINER_H


pcontainer.h:

#pragma once
#ifndef PCONTAINER_H
#define PCONTAINER_H

#include "container.h"

class StorableElement
{
public:
virtual void print()=0;
};

class Iterator
{
private:
public:
virtual bool hasNext()=0;
virtual StorableElement *next()=0;
};

class PervertedContainer
{
private:
Container<StorableElement *> f_cont;
PervertedContainer(const PervertedContainer&);
const PervertedContainer& operator=(const PervertedContainer&);
public:
class ListIterator:public Iterator
{
friend class PervertedContainer;
private:
Container<StorableElement *>::Iterator f_it;
ListIterator();
ListIterator(Container<StorableElement *>& cont);
public:
ListIterator(const ListIterator&);
const ListIterator& operator=(const ListIterator&);
~ListIterator();

bool hasNext();
StorableElement *next();
};
typedef void(*cont_handle)(StorableElement *data);
PervertedContainer();
~PervertedContainer();
static PervertedContainer *allocate();
static void release(PervertedContainer *cont);
void add(StorableElement *el);
void insert(const int pos,StorableElement *el);
int size()const;
StorableElement *get(const int pos);
StorableElement *replace(const int pos,StorableElement *el);
StorableElement *remove(const int pos);
void foreach(cont_handle proc);
void foreach_reverse(cont_handle proc);
ListIterator iterator();
};

#endif //PCONTAINER_H


test.h
#pragma once
#ifndef TEST_H
#define TEST_H

#include "pcontainer.h"

class TestStorableElement:public StorableElement
{
private:
public:
int f_data;
void print();
};

#endif //TEST_H


cmanager.cpp
#include <iostream>
#include <exception>
#include "cmanager.h"
#include "command.h"

CManager::CManager(std::ifstream& fin)
{
while(!fin.eof())
{
std::string name;
std::string arg;
getline(fin,name,' ');
getline(fin,arg,'\n');
if(name.length())
{
try
{
Command *cmd=Command::create(name);
cmd->init(arg);
f_command_list.add(cmd);
}
catch(std::exception& exc)
{
std::cout<<"Error: "<<exc.what()<<std::endl;
}
}
}
}

CManager::~CManager()
{
}

namespace
{
void exec_proc(StorableElement *el)
{
Command *cmd=dynamic_cast<Command *>(el);
if(cmd)
{
try
{
cmd->execute();
}
catch(std::exception& exc)
{
std::cout<<"Error: "<<exc.what()<<std::endl;
}
}
}
}

void CManager::execute()
{
f_command_list.foreach(exec_proc);
}


command.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <exception>
#include "command.h"

//--------------------------------------------------------------------------
// Command
//--------------------------------------------------------------------------

Command *Command::create(std::string name)
{
if(PrintCommand::f_name==name)
{
return PrintCommand::create();
}
if(CreateCommand::f_name==name)
{
return CreateCommand::create();
}
if(ExecCommand::f_name==name)
{
return ExecCommand::create();
}
if(IncCommand::f_name==name)
{
return IncCommand::create();
}
if(DecCommand::f_name==name)
{
return DecCommand::create();
}
if(ViewCommand::f_name==name)
{
return ViewCommand::create();
}
throw std::exception("unknown command");
}

//--------------------------------------------------------------------------
// PrintCommand
//--------------------------------------------------------------------------


const std::string PrintCommand::f_name="print";

PrintCommand::PrintCommand()
{
}

PrintCommand *PrintCommand::create()
{
return new PrintCommand;
}

void PrintCommand::print()
{
std::cout<<f_name;
}

void PrintCommand::init(std::string arg)
{
f_arg=arg;
}

void PrintCommand::execute()
{
std::cout<<f_arg<<std::endl;
}

//--------------------------------------------------------------------------
// CreateCommand
//--------------------------------------------------------------------------


const std::string CreateCommand::f_name="createfile";

CreateCommand::CreateCommand()
{
}

CreateCommand *CreateCommand::create()
{
return new CreateCommand;
}

void CreateCommand::print()
{
std::cout<<f_name;
}

void CreateCommand::init(std::string arg)
{
f_arg=arg;
}

void CreateCommand::execute()
{
std::ofstream fout;
fout.open(f_arg.c_str(),std::ios_base::out);
if(!fout.is_open())
{
throw std::exception("bad file");
}
std::string input_string;
getline(std::cin,input_string);
fout<<input_string;
fout.close();
}

//--------------------------------------------------------------------------
// ExecCommand
//--------------------------------------------------------------------------


const std::string ExecCommand::f_name="exec";

ExecCommand::ExecCommand()
{
}

ExecCommand *ExecCommand::create()
{
return new ExecCommand;
}

void ExecCommand::print()
{
std::cout<<f_name;
}

void ExecCommand::init(std::string arg)
{
f_arg=arg;
}

void ExecCommand::execute()
{
::system(f_arg.c_str());
}

//--------------------------------------------------------------------------
// IncCommand
//--------------------------------------------------------------------------


const std::string IncCommand::f_name="increment";

IncCommand::IncCommand()
{
}

IncCommand *IncCommand::create()
{
return new IncCommand;
}

void IncCommand::print()
{
std::cout<<f_name;
}

void IncCommand::init(std::string arg)
{
f_arg=arg;
}

void IncCommand::execute()
{
int value=0;
{
std::ifstream fin;
fin.open(f_arg.c_str(),std::ios_base::in);
if(!fin.is_open())
{
throw std::exception("bad file");
}
fin>>value;
if(fin.fail())
{
throw std::exception("bad integer");
}
fin.close();
}
{
std::ofstream fout;
fout.open(f_arg.c_str(),std::ios_base::out | std::ios_base::trunc);
if(!fout.is_open())
{
throw std::exception("bad file");
}
fout<<(value+1);
fout.close();
}
}

//--------------------------------------------------------------------------
// DecCommand
//--------------------------------------------------------------------------


const std::string DecCommand::f_name="decrement";

DecCommand::DecCommand()
{
}

DecCommand *DecCommand::create()
{
return new DecCommand;
}

void DecCommand::print()
{
std::cout<<f_name;
}

void DecCommand::init(std::string arg)
{
f_arg=arg;
}

void DecCommand::execute()
{
int value=0;
{
std::ifstream fin;
fin.open(f_arg.c_str(),std::ios_base::in);
if(!fin.is_open())
{
throw std::exception("bad file");
}
fin>>value;
if(fin.fail())
{
throw std::exception("bad integer");
}
fin.close();
}
{
std::ofstream fout;
fout.open(f_arg.c_str(),std::ios_base::out | std::ios_base::trunc);
if(!fout.is_open())
{
throw std::exception("bad file");
}
fout<<(value-1);
fout.close();
}
}

//--------------------------------------------------------------------------
// ViewCommand
//--------------------------------------------------------------------------


const std::string ViewCommand::f_name="viewfile";

ViewCommand::ViewCommand()
{
}

ViewCommand *ViewCommand::create()
{
return new ViewCommand;
}

void ViewCommand::print()
{
std::cout<<f_name;
}

void ViewCommand::init(std::string arg)
{
f_arg=arg;
}

void ViewCommand::execute()
{

std::ifstream fin;
fin.open(f_arg.c_str(),std::ios_base::in);
if(!fin.is_open())
{
throw std::exception("bad file");
}
std::string line;
while(!fin.eof())
{
getline(fin,line);
std::cout<<line<<std::endl;
}
fin.close();
}


main.cpp
#include <iostream>
#include <fstream>
#include "cmanager.h"

int main(int argc,char **argv)
{
if(argc < 2)
{
std::cout<<"too few arguments"<<std::endl;
}
std::ifstream fin;
fin.open(argv[1],std::ios_base::in);
if(!fin.is_open())
{
std::cout<<"bad file"<<std::endl;
}
CManager mgr(fin);
fin.close();
mgr.execute();
return 0;
}


pcontainer.cpp
#include "pcontainer.h"

PervertedContainer::PervertedContainer()
{

}

PervertedContainer::~PervertedContainer()
{

}

PervertedContainer *PervertedContainer::allocate()
{
try
{
return new PervertedContainer;
}
catch(...)
{
return 0;
}
}

void PervertedContainer::release(PervertedContainer *cont)
{
delete cont;
}

void PervertedContainer::add(StorableElement *el)
{
try
{
f_cont.add(el);
}
catch(...)
{
}
}

void PervertedContainer::insert(const int pos,StorableElement *el)
{
Container<StorableElement *>::Iterator it=f_cont.begin();
for(int i=0;i < pos;i++)
{
it++;
}
try
{
f_cont.insert(el,it);
}
catch(...)
{
}
}

int PervertedContainer::size()const
{
return f_cont.size();
}

StorableElement *PervertedContainer::get(const int pos)
{
try
{
return f_cont[pos];
}
catch(...)
{
return 0;
}
}

StorableElement *PervertedContainer::replace(const int pos,StorableElement *el)
{
Container<StorableElement *>::Iterator it=f_cont.begin();
for(int i=0;i < pos;i++)
{
it++;
}
try
{
StorableElement *old=(*it);
f_cont.remove(it);
insert(pos,el);
return old;
}
catch(...)
{
return 0;
}
}

StorableElement *PervertedContainer::remove(const int pos)
{
Container<StorableElement *>::Iterator it=f_cont.begin();
for(int i=0;i < pos;i++)
{
it++;
}
try
{ StorableElement *old=(*it);
f_cont.remove(it);
return old;
}
catch(...)
{
return 0;
}
}

void PervertedContainer::foreach(cont_handle proc)
{
for(Container<StorableElement *>::Iterator it=f_cont.begin();f_cont.end()!=it;it++)
{
proc(*it);
}
}

void PervertedContainer::foreach_reverse(cont_handle proc)
{
for(int i=f_cont.size()-1;i >= 0;i--)
{
proc(f_cont[i]);
}
}

PervertedContainer::ListIterator PervertedContainer::iterator()
{
return ListIterator(f_cont);
}


//--------------------------------------------------------------------------
// ListIterator
//--------------------------------------------------------------------------

PervertedContainer::ListIterator::ListIterator(Container<StorableElement *>& cont)
{
f_it=cont.begin();
}

PervertedContainer::ListIterator::ListIterator(const ListIterator& it)
{
f_it=it.f_it;
}

const PervertedContainer::ListIterator& PervertedContainer::ListIterator::operator=(const ListIterator& it)
{
if(this!=&it)
{
f_it=it.f_it;
}
return (*this);
}

PervertedContainer::ListIterator::~ListIterator()
{
}

bool PervertedContainer::ListIterator::hasNext()
{
return (!f_it.is_bad() && (f_it.get_parent()->end())!=f_it);
}

StorableElement *PervertedContainer::ListIterator::next()
{
if(hasNext())
{
StorableElement *old=*f_it;
f_it++;
return old;
}
return 0;
}


test.cpp
#include <iostream>
#include "test.h"
#include "pcontainer.h"

void TestStorableElement::print()
{
std::cout<<f_data;
}

void test()
{

}
Вот, в чем суть. Преподаватель сказал, что в задании четко указанны классы и их формат - нужно сделать соответствие, верно реализовать абстрактный класс - тут он неполный, и вообще не совсем соответствует указанному в задание - прошу помочь... другое было - просто посмотреть и разглядеть недочеты....вот тут вообще не ясно, т.е. очень просим помочь (видимо с точки зрения правильного или желательного написания программ или с точки зрения профессионального программиста - общие советы по написанию подобных программ). Главное все таки на тему абстрактного класса и дореализации тех методов что там указаны - очень надо, всю суть командного процессора уже сделали (основные методы сделаны, пограмма верно работает) - остались мелочи, но на них стопор, а сроки жмут...
Neonig
Друзья, понимаю, что россматривать столько нико не хочет, но я же не прошу писать, прошу совета, сам сделал сколько мог, а без помощи не обойтись....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.