IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

> Командный процессор, на с++
Neonig
сообщение 8.11.2007 19:23
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 25
Пол: Мужской

Репутация: -  -1  +


Здравствуйте.
В очередной раз взываю к помощи професионалов. У нас есть предмет ООП, там мы как бы разбиваемся на группы и выполняем задание, в общем такое задание один из участников реализовал, но выяснились недостатки и очевидные несоответствия с условием и все - переделать и доработать уже не можем, а сроки жмут. Далее представляю всю программу в исходнике. Задание следующее


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

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

Название Аргументы Описание Примеры
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()
{

}
Вот, в чем суть. Преподаватель сказал, что в задании четко указанны классы и их формат - нужно сделать соответствие, верно реализовать абстрактный класс - тут он неполный, и вообще не совсем соответствует указанному в задание - прошу помочь... другое было - просто посмотреть и разглядеть недочеты....вот тут вообще не ясно, т.е. очень просим помочь (видимо с точки зрения правильного или желательного написания программ или с точки зрения профессионального программиста - общие советы по написанию подобных программ). Главное все таки на тему абстрактного класса и дореализации тех методов что там указаны - очень надо, всю суть командного процессора уже сделали (основные методы сделаны, пограмма верно работает) - остались мелочи, но на них стопор, а сроки жмут...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 1)
Neonig
сообщение 15.11.2007 2:01
Сообщение #2


Новичок
*

Группа: Пользователи
Сообщений: 25
Пол: Мужской

Репутация: -  -1  +


Друзья, понимаю, что россматривать столько нико не хочет, но я же не прошу писать, прошу совета, сам сделал сколько мог, а без помощи не обойтись....
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 18.07.2025 20:39
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"