Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.05.2009, 15:59   #1
Roomper
Пользователь
 
Регистрация: 12.05.2008
Сообщений: 13
По умолчанию Задача на классы, перегрузка операторов [C++]

1. Создать класс для хранения календарных дат. Обеспечить возможность работы с датами в раз-личных форматах, изменения даты на заданное количество дней. Перегрузить операцию «–» для нахождения разности дат и операции сравнения. Для класса определить оператор <<. Стан-дартные функции и типы С для работы с датами не использовать.
2. Переопределить операции << и >> для ввода-вывода объектов класса data.


Вот, собственно, что у меня получилось:
Код:
//---------------------------------------------------------------------------
#pragma hdrstop
#include <iostream.h>
#include <iomanip.h>

//---------------------------------------------------------------------------

#pragma argsused

class data
{
	unsigned int day;
	unsigned int month;
	unsigned int year;

	public:
	static int type; 
	data(unsigned int d=1,unsigned int m=1,unsigned int=1);
	friend ostream& operator << (ostream& out,data& c);
	friend ostream& operator >> (ostream& in, data& c);
	friend bool operator == (const data&, const data&);
	void InputData(char *str);
};

data::data(unsigned int d, unsigned int m, unsigned int y)
{
	month = m;
	if (m > 12)
	{
		while (m > 12)
		{
			cout << "Input month <= 12! \n" << "Month: ";
			
			cin >> m;
		}
		month = m;
	 }
	 if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12))
	 {
		while (d > 31)
		{
			cout << "Input day <= 31! \n" << "Day: ";
			cin >> d;
		}
		day = d;			
	 }
	 if ((m == 4) || (m == 6) || (m == 9) || (m == 11))
	 {
		while (d > 30)
		{
			cout << "Input day <= 30! \n" << "Day: ";
			cin >> d;
		}
		day = d;
	 }
	 
	 if ((y%4 == 0) && (m == 2))
	 {
		while (d > 29)
		{
			cout << "Input day <= 29! \n" << "Day: ";
			cin >> d;
		} 
		day = d;   
	 }
	 
	 if ((y%4 != 0) && (m == 2))
	 {
		while (d > 28)
		{
			cout << "Input day <= 28! \n" << "Day: ";
			cin >> d;
		} 
		day = d; 		 
	 } 
	 year = y;

}
ostream& operator << (ostream& out, data& c)
{
		switch (c.type)
		{
			case 1: return out<<setw(2)<<setfill('0')<<c.day<<'.'
					<<setw(2)<<setfill('0')<<c.month<<'.'
					<<setw(4)<<setfill('0')<<c.year;
			case 2: return out<<setw(2)<<setfill('0')<<c.month<<'/'
					<<setw(2)<<setfill('0')<<c.day<<'/'
					<<setw(4)<<setfill('0')<<c.year;
			case 3: cout<<setw(2)<<setfill('0')<<c.day<<'-';
			switch (c.month)
			{
				case 1:cout<<"JAN-";break;
				case 2:cout<<"FEB-";break;
				case 3:cout<<"MAR-";break;
				case 4:cout<<"APR-";break;
				case 5:cout<<"MAY-";break;
				case 6:cout<<"JUN-";break;
				case 7:cout<<"JUL-";break;
				case 8:cout<<"AUG-";break;
				case 9:cout<<"SEP-";break;
				case 10:cout<<"OCT-";break;
				case 11:cout<<"NOV-";break;
				case 12:cout<<"DEC-";break;
			}
			return out << setw(4) << setfill('0') << c.year;

		}
		return out;
}
/*ostream& operator >> (ostream& in, data& c)
{
	switch (c.type)
	{
		case 1:
		case 2:
		case 3:
	}
	return in;
} */

bool operator == (const data& A, const data& B)
{
	if ((A.day==B.day) && (A.month==B.month) && (A.year==B.year)) return true;
	else return false;
}

void data::InputData(char *str)    //Ввод данных с клавиатуры
{
     char *tPtr;

	 tPtr=strtok(str,".");
	 day=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 month=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 year=atoi(tPtr);
}

int data::type;
int main(int argc, char* argv[])
{
	unsigned int day, month, year;
	
	cout << "Please make a choose the format of data: \n";
	cout << "1: DD.MM.YYYY \n2: MM/DD/YYYY \n3: DD-mon-YYYY \n";
	cin >> data::type;
	
	cout << "Input day, month and year of 1st date: ";
	cin >> day >> month >> year;
	data u(day, month, year);

	cout << u;

	cout << "\nInput day, month and year of 2nd date: ";
	cin >> day >> month >> year;
	data r(day, month, year);
	cout << r;
	if (u == r) cout << "\nDates are equal";
	else cout << "Dates aren't equal";
	char str[25];
	if(data::type == 1) cout << "\nVvedite datu v formate DD.MM.YYYY: ";
	else if (data::type == 2) cout << "\nVvedite datu v formate MM/DD/YYYY: ";
	else if (data::type == 3) cout << "\nVvedite datu v formate DD-mon-YYYY: ";
	cin >> str;
	data v;
	v.InputData(str);
	cout << v;
	getchar(); getchar();
	return 0;
}
//---------------------------------------------------------------------------
Получилось несколько громоздко, но иначе никак. Операцию вывода объектов для класса data у меня получилось переопределить, а вот с вводом объектов появились проблемы, в частности, не получается передать в переопределенный оператор строку, т.к. возможно объявление только с двумя параметрами. Функцию-метод то написал, а вот с >> никак не получается. Предложите свой вариант, буду оч благодарен.
Roomper вне форума Ответить с цитированием
Старый 22.05.2009, 19:34   #2
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Особо не вникал. И там, где я указал, еще нужно доработать для 3-го варианта:
Код:
#include <iostream.h>
#include <iomanip.h>

//---------------------------------------------------------------------------


class data
{
	unsigned int day;
	unsigned int month;
	unsigned int year;

	public:
	static int type; 
	data(unsigned int d=1,unsigned int m=1,unsigned int=1);
	friend ostream& operator << (ostream& out,data& c);
	friend istream& operator >> (istream& in, data& c);
	friend bool operator == (const data&, const data&);
	void InputData(char *str);
};

data::data(unsigned int d, unsigned int m, unsigned int y)
{
	month = m;
	if (m > 12)
	{
		while (m > 12)
		{
			cout << "Input month <= 12! \n" << "Month: ";
			
			cin >> m;
		}
		month = m;
	 }
	 if ((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12))
	 {
		while (d > 31)
		{
			cout << "Input day <= 31! \n" << "Day: ";
			cin >> d;
		}
		day = d;			
	 }
	 if ((m == 4) || (m == 6) || (m == 9) || (m == 11))
	 {
		while (d > 30)
		{
			cout << "Input day <= 30! \n" << "Day: ";
			cin >> d;
		}
		day = d;
	 }
	 
	 if ((y%4 == 0) && (m == 2))
	 {
		while (d > 29)
		{
			cout << "Input day <= 29! \n" << "Day: ";
			cin >> d;
		} 
		day = d;   
	 }
	 
	 if ((y%4 != 0) && (m == 2))
	 {
		while (d > 28)
		{
			cout << "Input day <= 28! \n" << "Day: ";
			cin >> d;
		} 
		day = d; 		 
	 } 
	 year = y;

}
ostream& operator << (ostream& out, data& c)
{
		switch (c.type)
		{
			case 1: return out<<setw(2)<<setfill('0')<<c.day<<'.'
					<<setw(2)<<setfill('0')<<c.month<<'.'
					<<setw(4)<<setfill('0')<<c.year;
					break;
			case 2: return out<<setw(2)<<setfill('0')<<c.month<<'/'
					<<setw(2)<<setfill('0')<<c.day<<'/'
					<<setw(4)<<setfill('0')<<c.year;
					break;
			case 3: cout<<setw(2)<<setfill('0')<<c.day<<'-';
			switch (c.month)
			{
				case 1:cout<<"JAN-";break;
				case 2:cout<<"FEB-";break;
				case 3:cout<<"MAR-";break;
				case 4:cout<<"APR-";break;
				case 5:cout<<"MAY-";break;
				case 6:cout<<"JUN-";break;
				case 7:cout<<"JUL-";break;
				case 8:cout<<"AUG-";break;
				case 9:cout<<"SEP-";break;
				case 10:cout<<"OCT-";break;
				case 11:cout<<"NOV-";break;
				case 12:cout<<"DEC-";break;
			}
			return out << setw(4) << setfill('0') << c.year;

		}
		return out;
}
istream& operator >> (istream& in, data& c)
{
 char str[100],*tPtr;
 in.getline(str,100,'\n');
	switch (c.type)
	{
		case 1: tPtr=strtok(str,".");
	 c.day=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 c.month=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 c.year=atoi(tPtr);
    break;
		case 2:
   tPtr=strtok(str,"/");
	 c.month=atoi(tPtr);

	 tPtr = strtok(NULL,"/");
	 c.day=atoi(tPtr);

	 tPtr = strtok(NULL,"/");
	 c.year=atoi(tPtr);
    break;
		case 3:
   tPtr=strtok(str,"-");
	 c.day=atoi(tPtr);

	 tPtr = strtok(NULL,"-");
	 c.month=atoi(tPtr);
	 // вот тут только месяц, как я понял, будет задан строкой. Поэтому нужно 
	   // разбирать через switch

	 tPtr = strtok(NULL,"-");
	 c.year=atoi(tPtr);
    break;
	}
	return in;
} 

bool operator == (const data& A, const data& B)
{
	if ((A.day==B.day) && (A.month==B.month) && (A.year==B.year)) return true;
	else return false;
}

void data::InputData(char *str)    //Ввод данных с клавиатуры
{
     char *tPtr;

	 tPtr=strtok(str,".");
	 day=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 month=atoi(tPtr);

	 tPtr = strtok(NULL,".");
	 year=atoi(tPtr);
}

int data::type;
int main(int argc, char* argv[])
{
	unsigned int day, month, year;
	
	cout << "Please make a choose the format of data: \n";
	cout << "1: DD.MM.YYYY \n2: MM/DD/YYYY \n3: DD-mon-YYYY \n";
	cin >> data::type;
	
	cout << "Input day, month and year of 1st date: ";
	cin >> day >> month >> year;
	data u(day, month, year);

	cout << u;

	cout << "\nInput day, month and year of 2nd date: ";
	cin >> day >> month >> year;
	data r(day, month, year);
	cout << r;
	if (u == r) cout << "\nDates are equal";
	else cout << "Dates aren't equal";
	char str[25];
	if(data::type == 1) cout << "\nVvedite datu v formate DD.MM.YYYY: ";
	else if (data::type == 2) cout << "\nVvedite datu v formate MM/DD/YYYY: ";
	else if (data::type == 3) cout << "\nVvedite datu v formate DD-mon-YYYY: ";
	cin >> str;
	data v;
	v.InputData(str);
	cout << v;
	getchar(); getchar();
	return 0;
}
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 22.05.2009, 23:09   #3
Roomper
Пользователь
 
Регистрация: 12.05.2008
Сообщений: 13
По умолчанию

Все бы хорошо было бы, если программа не зависала в момент ввода даты, исходя от выбранного формата. Вот после этого условного ветвления:
Код:
if(data::type == 1) cout << "\nVvedite datu v formate DD.MM.YYYY: ";
	else if (data::type == 2) cout << "\nVvedite datu v formate MM/DD/YYYY: ";
	else if (data::type == 3) cout << "\nVvedite datu v formate DD-mon-YYYY: ";
перед
Код:
data v;
cin >> v;
Сам код функции main:
Код:
int main(int argc, char* argv[])
{
	unsigned int day, month, year;

	cout << "Please make a choose the format of data: \n";
	cout << "1: DD.MM.YYYY \n2: MM/DD/YYYY \n3: DD-mon-YYYY \n";
	cin >> data::type;

	cout << "Input day, month and year of 1st date: ";
	cin >> day >> month >> year;
	data u(day, month, year);

	cout << u;

	cout << "\nInput day, month and year of 2nd date: ";
	cin >> day >> month >> year;
	data r(day, month, year);

	cout << r;

	if (u == r) cout << "\nDates are equal";
	else cout << "Dates aren't equal";
	char str[25];
	if(data::type == 1) cout << "\nVvedite datu v formate DD.MM.YYYY: ";
	else if (data::type == 2) cout << "\nVvedite datu v formate MM/DD/YYYY: ";
	else if (data::type == 3) cout << "\nVvedite datu v formate DD-mon-YYYY: ";

	data v;
	cin >> v;

	getchar(); getchar();
	return 0;
}
Roomper вне форума Ответить с цитированием
Старый 22.05.2009, 23:18   #4
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Цитата:
Сообщение от Roomper
если программа не зависала в момент ввода даты
У меня ничего не зависает.
Вот пример ввода:
Код:
Please make a choose the format of data:
1: DD.MM.YYYY
2: MM/DD/YYYY
3: DD-mon-YYYY
1
Input day, month and year of 1st date: 11 11 1999
11.11.1999
Input day, month and year of 2nd date: 11 11 1999
11.11.1999
Dates are equal

Vvedite datu v formate DD.MM.YYYY:
Совет: внимательно посмотрите, КАК вы должны вводить данные (исходя из кода главной функции).
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 23.05.2009, 09:35   #5
Roomper
Пользователь
 
Регистрация: 12.05.2008
Сообщений: 13
По умолчанию

Первый вариант ввода даты, где дата разделяется пробелами - тестовый. В нем введные данные записываются в переменные, которые потом передаются в конструктор.
Код:
cin >> day >> month >> year;
data u(day, month, year);
А мне нужно, чтоб сразу введенная преобразованная строка (например, 23.5.2009) вводилась в объект класса data. Вот таким же образом, как и выводится:
Код:
data r(day, month, year);
cout << r;
data v;
cin >> v;
Разве такое невозможно?
Roomper вне форума Ответить с цитированием
Старый 23.05.2009, 12:40   #6
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Цитата:
Разве такое невозможно?
Возможно, конечно. Но вы сказали, что у вас программа зависает. Я потестил и выявил, что такое случается, когда вы пытаетесь ввести дату в определенном формате при тестовом вводе (когда через пробелы нужно вводить). О чем вам и сказал.


Сделайте такую главную функцию:
Код:
int main(int argc, char* argv[])
{
	unsigned int day, month, year;

	cout << "Please make a choose the format of data: \n";
	cout << "1: DD.MM.YYYY \n2: MM/DD/YYYY \n3: DD-mon-YYYY \n";
	cin >> data::type;
 getchar();
	cout << "Input day, month and year of 1st date: ";
/*	cin >> day >> month >> year;
	data u(day, month, year); */

	data u;
	cin>>u;
	cout<<endl<<"Your date: \n";
	cout << u;



	getch();
	return 0;
}
И все будет вводиться в нужном формате. (пример для первого варианта)
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 23.05.2009, 13:23   #7
Roomper
Пользователь
 
Регистрация: 12.05.2008
Сообщений: 13
По умолчанию

Спасибо, разобрался Всего-то нужно было написать строчку getchar(); перед вводом данных в форматированном виде. А вообще, почему программа зависает, если не использовать функцию getchar()? По идее, это функцию используют перед нажатием клавиши ENTER чтоб консоль не закрывалась раньше времени.
Roomper вне форума Ответить с цитированием
Старый 23.05.2009, 13:25   #8
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Цитата:
По идее, это функцию используют перед нажатием клавиши ENTER чтоб консоль не закрывлась.

getchar считывает один символ. Просто после ввода даты в буфере остается символ перевода строки ('\n'), который успешно считывается в следующем выражении. Поэтому от него нужно избавиться.
Вместо getchar можно также просто очистить буфер - _flushall().
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 25.05.2009, 15:10   #9
Roomper
Пользователь
 
Регистрация: 12.05.2008
Сообщений: 13
По умолчанию

В дополнении к этому классу я переопределил операцию " - " для нахождения разности дат. Вот сам код оператора (прототип приводить не буду):
Код:
data operator - (data d1, data d2)
{
	data d3;
	d3.year=(d1.year-d2.year);

	if((d1.month-d2.month)<0)
		{d3.month=((d1.month-d2.month)+12);d3.year-=1;}
	else d3.month=(d1.month-d2.month);

	if(((d1.day-d2.day)<0) && (d3.month=d3.JAN))
		{d3.day=((d1.day-d2.day)-31);d3.month-=1;}

	if(((d3.year%4)==0)&&(d3.month==d3.MAR)&&((d1.day-d2.day)<0))
		{d3.month-=1;d3.day=(d1.day-d2.day+29);}

	if(((d3.year%4)!=0)&&(d3.month==d3.MAR)&&((d1.day-d2.day)<0))
		{d3.month-=1;d3.day=(d1.day-d2.day+28);}

	if(((d1.day-d2.day)<0)&&((d3.month==d3.APR)||(d3.month==d3.AUG)||(d3.month==d3.SEP)||
	(d3.month==d3.NOV)))
		{d3.month-=1; d3.day=(d1.day-d2.day+31);}

	if(((d1.day-d2.day)<0)&&((d3.month==d3.MAY)||(d3.month==d3.JUL)||(d3.month==d3.OCT)||
	(d3.month==d3.DEC)))
		{d3.month-=1;d3.day=(d1.day-d2.day+30);}

	return d3;
}
Но видимо где-то ошибся в алгоритме, т.к. неправильно вычисляется разность. В результате вычисления разности некоторых двух дат получается пятизначный, а то и шестизначный месяц...
Может уже есть готовые функции для работы с датами? Там в любом случае наверно есть вычисление разности дат. Вот код бы сравнить с моим.

Последний раз редактировалось Roomper; 25.05.2009 в 15:16.
Roomper вне форума Ответить с цитированием
Старый 25.05.2009, 16:36   #10
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

У меня ругается на неизвестные идентификаторы (MAR, APR...)/.
Кстати, у вас опечатка:
Код:
if(((d1.day-d2.day)<0) && (d3.month==d3.JAN))
Цитата:
Может уже есть готовые функции для работы с датами?
Посмотрите в стандартной библиотеке. Файл time.h.
http://www.cplusplus.com/reference/clibrary/ctime/
А еще лучше в справочнике Шилдта посмотрите.
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача в Делфи, классы. Катерина_Ио Фриланс 3 18.05.2009 14:10
Перегрузка операторов <<, >>, +=, +. class data Наташенька Общие вопросы C/C++ 2 02.05.2009 10:04
Перегрузка операторов (С++) Перчитель Помощь студентам 1 03.12.2008 18:46
Перегрузка операторов, Организация перегрузки операторов chagin_yav Помощь студентам 2 12.05.2008 09:15