Форум программистов, компьютерный форум CyberForum.ru

Переделать в классе-календаре функцию нормализации дней в месяце. - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Поиск числа в файле, открытым в бинарном режиме http://www.cyberforum.ru/cpp-beginners/thread1182955.html
Здравствуйте уважаемые дамы и господа, возник вопрос по поводу поиска числа в бинарном файле. Допустим имеется код: #include <iostream> #include <conio.h> using namespace std; void main(){ int t = 247; t = t - 246; cout << t << endl;
C++ Упаковка std :: vector <bool> в байты Добрый Вечер! возникла проблема: нужно элементы std::vector<bool> упаковать в байты для последующей записи в файл собственно, вопроса два: 1. как это сделать? 2. как потом нужно поступить с файлом (какие функции использовать и открывать ли файл в бинарном режиме для этого?) http://www.cyberforum.ru/cpp-beginners/thread1182954.html
C++ Проблема с перегрузкой операторов "+" и "+=" для классов Point и Circle
Есть класс Point (элементы данных x,y) и класс Circle (элементы данных р(типа Point),r). Их заголовочные файлы: class Point { private: double x, y; public: Point(); Point(double a, double b); Point(const Point &obj); Point move(double a, double b);
Копировать элемент из массива в массив C++
У меня есть два динамические массивы skydiver **mas=new skydiver* skydiver **masinplane=new skydiver* Первый массив содержит следующие элементы. mas=new skydiverpro("Михайло",200,400,0,0);all++; mas=new skydiverbuff("Олександр",400,400,0,0);all++;
C++ Описать класс, реализующий тип данных "вещественная матрица" http://www.cyberforum.ru/cpp-beginners/thread1182905.html
Задание: Описать класс, реализующий тип данных "вещественная матрица" и работу с ними. Класс должен реализовывать следующие операции над матрицами: 1. Методы, реализующие проверку типа матрицы (квадратная, диагональная, нулевая, единичная, симметричная, верхняя треугольная, нижняя треугольная). 2. Операции сравнения на равенство и неравенство. 3. Доступ к элементу по индексам Написать...
C++ Для знающих. Создаю меню в Borland C++, но что-то не работает, кто подскажет.что не так Файл с программой прилагается. меню из 4 пунктов но почему то не отображает их, кто сможет исправьте и отправите правильный вариант. Заранее спасибо подробнее

Показать сообщение отдельно
Dimsssss
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 20

Переделать в классе-календаре функцию нормализации дней в месяце. - C++

21.05.2014, 01:56. Просмотров 240. Ответов 0
Метки (Все метки)

В общем, нужно было написать календарь. Сделал я это, мягко говоря, не самым лучшим образом. А именно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#include <iostream>
#include <conio.h>
#include <time.h>
#include <math.h>
using namespace std;
 
class Date { //Класс "Дата"
    int year; //Год
    int month; //Месяц
    int day; //День
public:
    Date(int year, int month, int day); //Конструктор даты с заданными значениями
    bool is_leap_year(); //Функция, которая возвращает true, если год високосный и false в ином случае
    int get_year(); //Возвращаем значение года
    int get_month(); //Возвращаем значение месяца
    int get_day(); //Возвращаем значение дня
    friend class Calendar; //Дружественный класс "Календарь"
};
 
class Calendar { //Класс "Календарь"
    Date * date; //Указатель на текущую дату в календаре
    int months_duration[12]; //Массив, содержащий длительности месяцев в високосном году
    void normalize_months(); //Функция, приводящая в порядок номер месяца
    void normalize(); //Функция, приводящая в порядок всю дату
    void fill_months_duration(); //Функция, которая заполняет массив months_duration
public:
    Calendar(); //Конструктор по умолчанию. По умолчанию выставляется текущая дата
    Calendar(int year, int month, int day); //Конструктор с конкретной датой
    ~Calendar(); //Деструктор
    void set_date(int year, int month, int day); //Функция, которая задаёт дате значения
    void print(); //Функция, которая выводит дату
    void print_week_day(); //Функция, которая выводит день недели
    void add_year(int adding_year); //Функция, которая добавляет определённое кол-во лет к дате
    void add_month(int adding_month); //Функция, которая добавляет определённое кол-во месяцев к дате
    void add_day(int adding_day); //Функция, которая добавляет определённое кол-во дней к дате
    Date get_date(); //Функция, которая возвращает дату как объект
    int abs(int val);
};
 
int main() {
 
    Calendar * calendar = new Calendar(2014, 5, 14); //Создаём объект класса календарь под указателем calendar
    //Выводим список действий
    cout << "1 - set date" << endl << "2 - get current date" << endl
        <<"3 - print date (\"year.month.day\")" << endl
        << "4 - print week day" << endl << "5 - add day"
        << endl << "6 - add month" << endl << "7 - add year" << endl
        << "8 - exit" << endl;
    int q = 0; //В переменной q будем хранить выбор пользователя
    while (q != 8) { //Пока q не равно 8. (8 сответствует выходу из программы)
        q = _getch() - 48; //Считываем q
        switch (q) { //Делаем действия соответственно значению q
        case 1: //Пользователь устанавливает дату в календаре
            cout << "year month day: ";
            int day, month, year;
            cin >> year >> month >> day;
            calendar->set_date(year, month, day);
            break;
        case 2: //Устанавливаем текущую системную дату
            //calendar->set_current_date();
            cout << "Current date: ";
        case 3: //Выводим календарь
            calendar->print();
            break;
        case 4: //Выводим день недели
            calendar->print_week_day();
            break;
        case 5: //Пользователь добавляет определённое кол-во дней к дате
            cout << "how many days do you want to add? ";
            int days;
            cin >> days;
            calendar->add_day(days);
            break;
        case 6: //Пользователь доавляет определённое кол-во месяцев к дате
            cout << "how many months do you want to add? ";
            int months;
            cin >> months;
            calendar->add_month(months);
            break;
        case 7: //Пользователь добавляет определённое кол-во лет к дате
            cout << "how many years do you want to add? ";
            int years;
            cin >> years;
            calendar->add_year(years);
            break;
        case 8: //Выходим из программы. (цикл не продолжится, если q == 8)
            break;
        default: //Если же q не сответствует ни одной из опций, то выводим сообщение об ошибке
            cout << "Wrong command! Try again." << endl;
            break;
        }
    }
    delete calendar; //Удаляем календарь
    return 0;
}
 
Date::Date(int year, int month, int day) {
    //Присваиваем дате переданные значения
    this->year = year;
    this->month = month;
    this->day = day;
}
 
bool Date::is_leap_year() {
    //2012 - високосный
    //Если остаток от деления года на 4 равен 0, то этот год високосный и возвращаем true. В ином случае false.
    if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0))
        return 1;
    else
        return 0;
}
 
int Date::get_year() {
    return year; //Возвращаем значение года
}
 
int Date::get_month() {
    return month; //Возвращаем значение месяца
}
 
int Date::get_day() {
    return day; //Возвращаем значение дня
}
 
void Calendar::fill_months_duration() {
    //Задаём массив, в котором будем хранить кол-во дней в месяцах в високосном году
    int months[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    //Копируем каждый элемент заданного массива в массив объекта календарь.
    for (int i = 0; i < 12; i++)
        months_duration[i] = months[i];
    //По другому с массивами никак не получается - компилятор ругается :(
}
 
Calendar::Calendar() {
    fill_months_duration(); //Заполняем массив months_duration
    //set_current_date(); //Устанавливаем текущую дату
}
 
Calendar::Calendar(int year, int month, int day) {
    fill_months_duration(); //Заполняем массив months_duration
    set_date(year, month, day); //Устанавливаем дату согласно переданным значениям
}
 
Calendar::~Calendar() {
    delete this->date; //Удаляем дату
}
 
 
 
void Calendar::set_date(int year, int month, int day) {
    //Если день больше нуля и не больше кол-ва дней в этом месяце и месяц нах-ся в промежутке от 1 до 12,
    //а также если это не 29 февраля невисокосного года
    if (day > 0 && day <= months_duration[month-1] && month > 0 && month < 13 && !(month == 2 && day == 29 && (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) )) {
        delete this->date; //Удаляем дату
        this->date = new Date(year, month, day); //Создаём под указателем даты новую дату с заданной датой
    } else cout << "Error in date!" << endl; //Иначе пишем сообщение об ошибке
}
 
 
void Calendar::add_day(int adding_day) {
    date->day += adding_day; //Увеличиваем кол-во дней на введённое пользователем значение
    normalize(); //Приводим в порядок Дату
}
 
void Calendar::add_year(int adding_year) {
    date->year += adding_year; //Прибавляем к году введённое пользователем значение
    //Проверяем, не получилось ли у нас 29 февраля в невисокосном году
    if (date->month == 2 && date->day == 29 && !date->is_leap_year())
        //Если это так, то уменьшим кол-во дней на 1
            date->day--;
}
 
void Calendar::add_month(int adding_month) {
    date->month += adding_month; //Прибавляем к месяцу значение, которое ввёл пользователь
    normalize();  //Приводим в порядок Дату
}
 
void Calendar::print() {
    //Выводим дату в формате "Год.Месяц.День"
    cout << "\"" << date->year << "." << date->month << "." << date->day << "\"" << endl;
}
 
int Calendar::abs(int val) {
    return val < 0 ? -val : val;
}
 
void Calendar::print_week_day() {
    //2013-01-01 = Вторник - известная дата с днём недели
    int days_difference; //Переменная, в которую запишем разницу в днях от заданной даты до известной
 
    int years_difference = date->year - 2013; //Вычисляем разницу в годах между заданной и известной датой
    int leap_years_count = abs(years_difference / 4); //Вычисляем сколько в этом годовом промежутке високосных лет
    if (date->is_leap_year()) //Если же сама наша дата является високосным годом
        leap_years_count++; //Увеличиваем счётчик високосных лет на один
    //Если заданный год меньше известного и 2012 год остался неучтённым в качестве високосного
    if (years_difference < 0 && years_difference > -4 && date->year != 2012)
        leap_years_count++; //Увеличиваем счётчик високосных лет на один
    //Умножаем разницу в годах на кол-во дней в невисокосном году и записываем результат в переменную
    days_difference = years_difference * 365;
    if (days_difference >= 0) //Если разница в днях неотрицательна
        //Прибавляем к переменной кол-во високосных лет, по сути учитываем то, что в високосном году на 1 день больше
            days_difference += leap_years_count;
    //В ином случае наоборот вычитаем кол-во високосных лет
    else days_difference -= leap_years_count;
 
    //Учитываем разницу в месяцах.
    for (int i = 0; i < date->month - 1; ++i) {
        if (i == 1 && !date->is_leap_year()) //Если год невисокосный и i соответствует февралю
            days_difference += 28; //Увеличиваем переменную на 28
        //В ином случае увеличиваем переменную на соответствующее месяцу кол-во дней
        else days_difference += months_duration[i];
    }
 
    //Учитываем разницу в днях(день месяца)
    days_difference += date->day; //Прибавляем к переменной номер дня в месяце
    days_difference--; //Вычитаем 1, тк базовый день - первое число месяца
 
 
    //(days_difference + 1) и (days_difference - 5) потому что базовый день - вторник
    //По особым формулам, учитывающим, что разница в днях может быть как отрицательной, так и положительной,
    //а также то, что базовым днём является вторник, получаем в переменной число от 0 до 6, которое и покажет
    //нам день недели
    if (days_difference > 0)
        days_difference = (days_difference + 1) % 7;
    else days_difference = 6 + (days_difference - 5) % 7;
 
    //Каждой цифре от 0 до 6 соответствует день недели. Выводим соответствующий день недели.
    switch (days_difference) {
    case 0: cout << "Monday";
        break;
    case 1: cout << "Tuesday";
        break;
    case 2: cout << "Wednesday";
        break;
    case 3: cout << "Thursday";
        break;
    case 4: cout << "Friday";
        break;
    case 5: cout << "Saturday";
        break;
    case 6: cout << "Sunday";
        break;
        //Если переменная по каким-то причинам оказалась не в промежутке от 0 до 6, то
        //выведем это число и сообщение об ошибке :(.
    default: cout << "Error! days difference = " << days_difference;
        break;
    }
    cout << endl;
}
 
void Calendar::normalize_months() {
    if (date->month > 12 || date->month < 1) { //Если номер месяца больше 12 или меньше одного
        date->year += date->month / 12; //Прибавляем столько лет, сколько раз в месяцах укладывается по 12
        date->month %= 12; //Месяцам присваиваем значение, равное остатку от их деления на 12
        if (date->month < 1) { //Если месяц меньше одного
            date->year--; //Уменьшаем год на 1
            date->month += 12; //Прибавляем к месяцу 12
        }
    }
}
 
void Calendar::normalize() {
    normalize_months(); //Вызываем функцию, которая приводит в порядок номер месяца
    while ((date->day > 365)||(date->day < 0)) //пока количество дней больше, чем в году или меньше единицы
    {
    int years_pass = date->day/365; //присваиваем переменной years_pass целую часть от деления кол-ва дней на 365
    date->day %= 365; //дням присваиваем остаток от деления дней на 365
    int current_year = date->year; //переменной задаем значение номера года, к которому прибавляем дни
        if (date->day > 0) //если дней больше 0
        {
        for (int m = current_year; m < (current_year + years_pass); m++) //от начала и до конца временного интервала в годах
        {
            if (date->is_leap_year()) //если год високосный
            {
                date->day--; //вычесть день из date->day
            }
            date->year++; //увеличить date->year
        }
        if (date->day < 0) //если цикл навычитал дней столько, что их значение стало отрицательным
        {
            if (date->is_leap_year()) //если год високосный
            {
                date->year--; //вычесть 1 год
                date->day += 366; //прибавить к дням 366 дней
            }
            if (!(date->is_leap_year())) //если год невисокосный
            {
                date->year--; //вычесть 1 год
                date->day += 365; //прибавить к дням 365 дней
            }
        }
        }
            if (date->day < 0) //если дней меньше 0
            {
            for (int m = current_year; m > (current_year + years_pass); m--) //от начала и до конца временного интервала в годах
            {
                if (date->is_leap_year()) //если год високосный
                {
                    date->day++; //добавить день в date->day
                }
                date->year--; //уменьшить date->year
            }
            if (date->day > 365) //если цикл наверху наприбавлял нам дней больше, чем на год
            {
                if (date->is_leap_year()) //если год високосный
                {
                    date->year++; //добавим 1 год
                    date->day -= 366; //отнимем 366 дней
                }
                if (!(date->is_leap_year())) //если год невисокосный
                {
                    date->year++; //добавим 1 год
                    date->day -= 365; //отнимем 365 дней
                }
            }
            }
    if (date->day == 366 && !date->is_leap_year()) //Если в остатке 366 дней и это не високосный год
        {
            date->year++; //Увеличиваем кол-во лет на 1
            date->day = 1; //Кол-ву дней присваиваем значение 1
        }
    }
    while (date->day > months_duration[date->month - 1]) { //Пока дни в дате больше чем кол-во дней в месяце
           if (!date->is_leap_year() && date->month == 2) { //Если год невисокосный и на дворе февраль
               date->day -= 28; //Отнимаем 28 дней
               date->month++; //Увеличиваем кол-во месяцев на 1
           } else { //В ином случае
               //Отнимаем от дней соответствующее месяцу кол-во дней в месяце
               date->day -= months_duration[date->month - 1];
               date->month++; //Увеличиваем кол-во месяцев на 1
               normalize_months(); //Вызываем функцию, которая приводит в порядок номер месяца
           }
    }
    if ((!date->is_leap_year() && date->month == 2 && date->day == 29)) { //если год невисокосный, месяц февраль и в остатке 29 дней
            date->month++; //Увеличиваем кол-во месяцев на 1
            date->day = 1; //Кол-во дней приравниваем к 1. (29 - 28)
        }
}
 
Date Calendar::get_date() {
    return * date; //Возвращаем разыменованную ссылку на дату
}
Можете ли вы помочь мне исправить функцию normalize? Дело в том, что циклов там быть не должно, либо должны они юзаться по минимуму. Я пришел к идее того, что на каждый месяц должен быть свой список с количеством дней. Год должен быть списком месяцев. Задача в том, что когда мы добавляем дни, нужно отслеживать, меньше ли количество дней (в date->days), чем в месяце (months_duration [date->month+1]). Соответственно то же самое и для отношения месяцев к годам. Помогите сделать normalize через списки!!! Заранее спасибо
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 03:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru