Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

Курсов проект по ООП

Featured Replies

Здравейте!

Имам следните затруднения с курсов проект по ООП. Само една от функциите в условието не съм направил, тази, която не е с '+'. При стартиране на програмата в конзолата не зарежда абсолютно нищо, нито меню, нито файл. Само черен екран с мигащ курсор.

Цитат

 

I. Да се състави клас за филми CFilms с член променливи:

Заглавие на филма, продуцент, тираж, година на производство, жанр.

Съставете функции за:

+ 1. за установяване на член променливите

+ 2. функции за извеждане в изходен поток (отделно файл, отделно конзола)

Съставете конструктори:

+ 1. Подразбиращ

+ 2. Експлицитен

+ 3. Копиращ

Съставете функции за:

+ 1. Валидизиране на жанра

+ 2. Изчисляване възрастта на филма

+ 3. Извеждане данните за филма на принтер

+ 4. Оператор за присвояване

+ 5. Лог. оператор, проверяващ дали филмът е създаден през текуща година

+ 6. Оператор за сравнение > (по тираж)

+ 7. Оператор за съвпадение (по продуцент)

------------------------------------------------

II. Да се състави клас CRazprostranitel, който съдържа CFilms с член променливи име на разпространителя, брой филми, брой приходи за една година.

Съставете следните функции:

+ 1. Създаване на обект чрез друг обект

+ 2. Създаване на обект чрез експлицитно зададени параметри

+ 3. Функция, определяща дали филмът е предлаган повече от веднъж

--------------------------------------

III. Съставете главна програма, илюстрираща използването на създадените класове. Да се създаде контейнер вектор от 10 обекта от класа CRazprostranitel и да се направят следните справки:

+ 1. Извеждане в отделен списък(list) на филмите с тираж на 50000 копия, от жанр комедия

- 2. да се изведат в отделни файлове всички разпространители, които разпространяват филми на едни и същи продуценти

+ 3 . да се изведат заглавията на филмите, които са над 20 за продуцент, чието име е подадено като параметър

+ 4. да се изведат всички данни за разпространителите с брой приходи, получени като параметър от текстов файл

+ 5. при подаден параметър година на производство, да се изведат разпространителите на такива филми, които са от жанр екшън или драма.

 

 

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <fstream>

using namespace std;

string Genres[9] = {"Драма", "Екшън", "Фантастика", "Ужаси", "Трилър", "Мистерия", "Комедия", "Криминален", "Документален"};

class CFilms
{
private:
	string m_strTitle, m_strProducer, m_strGenre;
	int m_iEdition, m_iYear;
public:
	//подразбиращ
	CFilms() { m_strTitle = "Unknown", m_strProducer = "Unknown", m_strGenre = "Unknown", m_iYear = 0, m_iEdition = 0; }
	//експлицитен
	CFilms(const string Title, const string Producer, const string Genre, const int Year, const int Edition)
	{
		m_strTitle = Title;
		m_strProducer = Producer;
		m_strGenre = Genre;
		m_iEdition = Edition;
		m_iYear = Year;
	}
	//копиращ
	CFilms(const CFilms& ToCopy)
	{
		m_strTitle = ToCopy.GetTitle();
		m_strProducer = ToCopy.GetProducer();
		m_strGenre = ToCopy.GetGenre();
		m_iEdition = ToCopy.GetEdition();
		m_iYear = ToCopy.GetYear();
	}
	//установяване на член-променливите
	void SetTitle(string Title) { m_strTitle = Title; }
	void SetProducer(string Producer) { m_strProducer = Producer; }
	void SetGenre(string Genre) { m_strGenre = Genre; }
	void SetEdition(int Edition) { m_iEdition = Edition; }
	void SetYear(int Year) { m_iYear = Year; }

	const string GetTitle() const { return m_strTitle; }
	const string GetProducer() const { return m_strProducer; }
	const string GetGenre() const { return m_strGenre; }
	const int GetEdition() const { return m_iEdition; }
	const int GetYear() const { return m_iYear; }

	//извеждане на екран
	friend ostream& operator<<(ostream& toStream, CFilms& object)
	{
		return toStream << "Movie title is: " << object.GetTitle() << ", Year: " << object.GetYear() << ", Genre: " << object.GetGenre() << ", Produced by: " << object.GetProducer() << endl;
	}

	//извеждане във файл
	ostream& Output(const string& Filename)
	{
		ofstream File(Filename);
		if (File)
		{
			File << "Movie title is: " << m_strTitle << ", Year: " << m_iYear << ", Genre: " << m_strGenre << ", Produced by: " << m_strProducer << "Editions: " << m_iEdition << endl;
		}
		else
			throw "File not found!";
	}

	//валидация на жанра
	bool GenreValidation(string Genre)
	{
		for (int i = 0; i < 9; i++)
		{
			if (Genres[i] == Genre)
				return true;
			else
				return false;
		}
	}

	//изчисляване на възрастта на филма
	int MoviesAge()
	{
		int iResult;
		iResult = 2017 - m_iYear;
		return iResult;
	}

	//извеждане на данните за филма на принтер
	void PrinterOutput()
	{
		CFilms array[10];
		ofstream PrinterFile("Print_movie");
		for (int i = 0; i < 10;i++)
		{
			PrinterFile << array[i];
			PrinterFile << endl;
		}
		PrinterFile.close();
	}

	//оператор =
	const CFilms operator=(const CFilms& object)
	{
		CFilms m_Temp(object);
		return m_Temp;
	}

	//логически оператор
	bool MovieYearCheck(int Year)
	{
		if (m_iYear == Year)
			return true;
		else
			return false;
	}

	//оператор >
	bool operator >(const CFilms& object) { return m_iEdition > object.m_iEdition; }
	//оператор за съвпадение
	bool operator ==(const CFilms& object) { return m_strProducer == object.m_strProducer; }
};

class CRazprostranitel : CFilms
{
private:
	vector<CFilms> m_vMovies;
	string m_strName;
	int m_iMovies, m_iRevenue;
public:
	CRazprostranitel() { m_strName = "Unknown", m_iMovies = 0, m_iRevenue = 0; }
	//експлицитен
	CRazprostranitel(vector<CFilms> Objects, const string Name, const int Movies, const int Revenue)
	{
		m_vMovies = Objects;
		m_strName = Name;
		m_iMovies = Movies;
		m_iRevenue = Revenue;
	}
	//обект чрез друг обект
	CRazprostranitel(const CRazprostranitel& object)
	{
		m_vMovies = object.m_vMovies;
		m_strName = object.m_strName;
		m_iMovies = object.m_iMovies;
		m_iRevenue = object.m_iRevenue;
	}

	//установяване на променливите
	vector<CFilms> GetMovies() const { return m_vMovies; }
	const string GetName() const { return m_strName; }
	const int GetNumberMovies() const { return m_iMovies; }
	const int GetRevenue() const { return m_iRevenue; }

	//провека за повече от веднъж
	bool ContentMovies(CFilms object)
	{
		int iCount = 0;
		for each (CFilms var in m_vMovies)
		{
			if (var == object) { iCount++; }
		}
		if (iCount > 1)
			return true;
		else
			return false;
	}
};

//функция за вектор от обекти
vector<CRazprostranitel> AddVector(string Filename, int Size)
{
	vector<CRazprostranitel> m_vObject;
	vector<CFilms> m_vFilms;
	string strName;
	int iCount_Movies, iCount_Revenue, Year, Edition, iCount = 0;
	string strTitle, strProducer, strGenre;
	ifstream File(Filename);
	if (!File)
	{
		throw "Файлът не е намерен!";
	}
	while (!File.eof() && iCount < Size)
	{
		getline(File, strName);
		File >> iCount_Movies >> iCount_Revenue;
		for (int i = 0;i < iCount_Movies;i++)
		{
			getline(File, strTitle);
			getline(File, strProducer);
			File >> Year;
			getline(File, strGenre);
			File >> Edition;
			m_vFilms.push_back(CFilms(strTitle, strProducer, strGenre, Year, Edition));
		}
		m_vObject.push_back(CRazprostranitel(m_vFilms, strName, iCount_Movies, iCount_Revenue));
		m_vFilms.clear();
	}
	return m_vObject;
}

//функция за извеждане на списък от филми
list<string> ListEdition(vector<CRazprostranitel> m_vObject)
{
	list<string> lstList;
	vector<CFilms> m_vFilms;
	bool flag = true;
	for each(CRazprostranitel var in  m_vObject)
	{
		m_vFilms = var.GetMovies();
		for each(CFilms film in m_vFilms)
		{
			if (film.GetEdition() > 50000 && film.GetGenre() == "Комедия")
			{
				lstList.push_back(film.GetTitle());
				flag = false;
			}
		}
		m_vFilms.clear();
	}
	if (flag)
		throw "Няма филми с тираж по-голям от 50000 копия.\n";
	else
		lstList.unique();
	return lstList;
}

//над 20 филма за продуцент
void ProducerMovies(vector<CRazprostranitel> m_vObject, string Name)
{
	list<string> lstList;
	vector<CFilms> m_vFilms;
	for each (CRazprostranitel var in m_vObject)
	{
		m_vFilms = var.GetMovies();
		for (int i = 0;(unsigned)i < m_vFilms.size();i++)
		{
			if (m_vFilms[i].GetProducer() == Name) { lstList.push_back(m_vFilms[i].GetTitle()); }
		}
	}
	if (lstList.size() > 20)
	{
		while (!lstList.empty())
		{
			cout << *lstList.begin() << endl;
			lstList.erase(lstList.begin());
		}
	}
	else
		throw "Продуцентът няма повече от 20 филма или не съществува!\n";	
}

//функция за приходи
void Revenues(vector<CRazprostranitel> m_vObject, string Filename)
{
	bool flag = true;
	int iRevenue;
	ifstream File(Filename);
	if (!File)
	{
		throw "Файлът не е намерен";
	}
	while (!File.eof())
	{
		File >> iRevenue;
		cout << "Приходи: " << iRevenue << "\t";
		for each(CRazprostranitel var in m_vObject)
		{
			if (var.GetRevenue() == iRevenue)
			{
				flag = false;
				cout << "\nИме на разпространител: " << var.GetName() << "\t" << var.GetNumberMovies() << endl;
			}
		}
		if (flag)
		{
			cout << "Няма разпространител с такива приходи\n";
		}
	}
}

//функция по година
void MoviesByYear(vector<CRazprostranitel> m_vObject, int Year)
{
	vector<CFilms> m_vFilms;
	bool flag = true;
	for each(CRazprostranitel var in m_vObject)
	{
		m_vFilms = var.GetMovies();
		for each(CFilms film in m_vFilms)
		{
			if (film.GetYear() == Year && (film.GetGenre() == "Екшън" || film.GetGenre() == "Драма"))
			{
				cout << var.GetName() << endl;
				flag = false;
				break;
			}
		}
		m_vFilms.clear();
	}
	if (flag)
	{
		cout << "Няма разпространители на филми от " << Year << " г.\n";
	}
}

int main()
{
	setlocale(LC_ALL, "BGR");	//кирилица

	list<string> lstFilms;
	int iChoice;
	try
	{
		vector<CRazprostranitel> m_vPropagator(10);
		m_vPropagator = AddVector("movies.txt", 10);
		do
		{
			system("cls");
			cout << "-------------Главно меню--------------" << endl;
			cout << "1. Извеждане на филми с тираж над 50000 копия от жанр комедия" << endl;
			cout << "2. Извеждане в отделни файлове на всички разпространители, "
				<< "които разпространяват филми на едни и същи продуценти" << endl;
			cout << "3. Извеждане на заглавията на филмите, които са над 20 за даден продуцент" << endl;
			cout << "4. Извеждане на всички данни за разпространителите с брой приходи, "
				<< "получени като параметър от входен файл" << endl;
			cout << "5. Извеждане на разпространителите на филми от жанр екшън или драма" << endl;
			cout << "6. Изход" << endl;
			cout << "Моля, изберете число между 1-6: ";
			cin >> iChoice;

			switch (iChoice)
			{
			case 1:
			{
				lstFilms = ListEdition(m_vPropagator);
				system("pause");
				break;
			}

			case 2:
			{
				//second fn(m_vPropagator);
				system("pause");
				break;
			}

			case 3:
			{
				string strName;
				cout << "\nВъведете име на продуцент: ";
				cin >> strName;
				ProducerMovies(m_vPropagator, strName);
				system("pause");
				break;
			}

			case 4:
			{
				string Filename;
				cout << "\nВъведете име на файл: ";
				cin >> Filename;
				Revenues(m_vPropagator, Filename);
				system("pause");
				break;
			}

			case 5:
			{
				int iYear;
				cout << "\nВъведете година: ";
				cin >> iYear;
				MoviesByYear(m_vPropagator, iYear);
				system("pause");
				break;
			}

			default:
				cout << "\nИзход от програмата.\n";
				exit(1);
			}
		} while (iChoice != 6);
	}
	catch (char* error)
	{
		throw "Error!\n";
	}

	return 0;
}
преди 9 часа, Иван Милкович написа:

setlocale(LC_ALL, "BGR"); //кирилица

Кодировката на сорс файла windows1251 ли ти е ?

Ако не е, кодирай го така. Виж в менюто на редактора ти как става

Това, ако изкарва маймуняци.

Ако нищо не изкарва, значи зацикля преди да стигнеш до извеждане на конзолата.

Пусни в режим дебъгер, като предварително сложиш брейкпойнт на 

m_vPropagator = AddVector("movies.txt", 10);

После със степ инту и след като влезеш в подпрограмата със степ оувър, изпълни стъпка по стъпка и виж къде зацикля

Почти няма вярна функция, вижда се, че се опитваш да пишеш, но знанията са ти "размити" или неусвоени.

На първо време

 try { ... } catch (const cher *error) { puts(error); }

в противен случай

 catch (char* error) { throw "Error!\n"; }

просто re-throw -ва изклюението и принуждаваш ОС да го прихване и унищожи програмата ти. Защото нямаш друг try {} catch блок на по-високо ниво, всичко извън видимостта на main функцията, т.е. в main() { } може да създаваш обекти и да слагаш колкото ти душа иска блокове за изключения, но "изпуснеш" изключение - програмата ти престава да работи независимо дали е стигнала своят край (последният ред)

На този ред m_vPropagator = AddVector("movies.txt", 10); се опитваш да отвориш файл с име movies.txt, който се намира в текущата директория на изпълнимият файл, ако не го намери програмата ти приключва, заради по-горното обяснение. Векторът е динамично разширяващ се контейнер, не е нужно да му задаваш размер (10).

vector<CRazprostranitel> m_vPropagator(10); -> това създава вектор с 10 елемента от тип CRazprostranitel като се извиква контруктора по подрабиране, няма слисъл да го правиш, защото още на следващият ред ти променяш изцяло съдържанието и размера му (извиква се vector& operator= (const vector& x)).

След това, такава конструкция никога не е съществувала в C++ for each(type x in y)

GenreValidation(string Genre) -> string Genre е предаване на парамеър по стойност т.е. копиране (нов обект), който може да променяш в областта на видимост на функцията (т.е. между { })

for (int i = 0; i < 9; i++)
{
	if (Genres[i] == Genre)
		return true;
	else
		return false;
}

Що за логика има тук, има 100% излизане от функцията още при проверката на първият елемент, ти искаш да провериш, дали подаденият жанр е този от поддържаните, верният код е

bool GenreValidation(const string &Genre)
{
  	for (int i = 0; i < 9; i++)
	{
		if (Genres[i] == Genre)
			return true;
	}
  	return false;
}

const CFilms operator=(const CFilms& object) -> оператор = никога не връща копие, гибу се целият му смисъл. Спирам някъде тук, поправи цялата програма или питай какво още не е ясно :)

  • Автор

Здрасти, благодаря за отговорите. Всичко вече ми върви, освен горе споменатата функция. А именно:  - 2. да се изведат в отделни файлове всички разпространители, които разпространяват филми на едни и същи продуценти

 

Опитах някак, но единственият резултат, който получавам е отделни файлове на всички продуценти, а в тях имената на разпространителите, но като че ли произволно подбрани.

 

void FileOutput(vector<CRazprostranitel> m_vObject)
{
	ofstream File;
	list<string> lstList;
	vector<CFilms> m_vFilms;
	for (int i = 0; i < (signed)m_vObject.size(); i++)
	{
		m_vFilms = m_vObject.at(i).GetMovies();
		for (int j = 0; j < (signed)m_vFilms.size(); j++)
		{
			lstList.push_back(m_vFilms.at(j).GetProducer());
		}
		m_vFilms.clear();
	}
	lstList.unique();
	list<string> razps;
	CreateDirectory(L"Razprostraniteli", NULL);
	for (auto it = lstList.begin(); it != lstList.end(); it++)
	{
		for (int i = 0; i < (signed)m_vObject.size(); i++)
		{
			m_vFilms = m_vObject.at(i).GetMovies();
			for (int j = 0; j < (signed)m_vFilms.size(); j++)
			{
				if (*it == m_vFilms.at(j).GetProducer())
					razps.push_back(m_vObject.at(i).GetName());
			}
			m_vFilms.clear();
		}
		razps.unique();
		File.open("Razprostraniteli\\" + *it + ".txt", ios::out);
		for (auto iter = razps.begin(); iter != razps.end(); iter++)
		{
			File << *iter << endl;
		}
		File.close();
	}
}

 

Виждам, че ползваш auto, което е C++11, в такъв случай може директно така

for(const auto &producer : lstList)

Това vector<CRazprostranitel> m_vObject е копие избягвай такава конструкция като параметър на функция -> (const vector<CRazprostranitel> &m_vObject)

Когато итерираш може да ползваш operator[] -> m_vObject.GetMovies() и най-добре auto m_vFilms = m_vObject.GetMovies() като не е нужно да викаш clear() това се прави респективно в оператор= или десктруктора.

Копиране на един ред -> for_each(m_vFilms.begin(), m_vFilms.end(), [&lstList](const auto &film) { lstList.push_back(film.GetProducer()); });

                                                          ^                             ^                           ^                               ^          ^

                                                          |                              |                            |                               |           |

                                       начало на контейнера         край             референция към               *it   тяло на ламбда функцията

                                                                                                  променлива от контекста

                                                                                               (референция, защото добавяме)

Когато използваш не прост тип (различен от int, short, long, float, double) for (auto it = lstList.begin(); it != lstList.end(); it++) it++ е копие -> operator++(int) по-добре е ++it

Не са произволно подбрани, а list<string> razps; трябва да е декларирано в цикъла, защото сега реално само добавяш и за всеки следващ продуцент имаш филмите на всеки предходен, т.е. сумираш ги до текущият.

  • Автор

Благодаря ти. Успях да ги подкарам, като промених на някои места кода. Извежда ми файлове с верните разпространители вътре. Сега остана само да направя обратното. Трябва във файловете да са имената на продуцентите, а имената на файловете да са с тези на разпространителите.

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    25%
    Дарени 252.69 EUR от нужните 1,000.00 EUR

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.