Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Доработать календарь, Не реагирует на нажатие стрелок  
:(
    Опции темы
zeitgeistz
Дата 3.5.2013, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Здравствуйте, ниже представленный код рисует календарь. Мне нужно, чтобы при нажатии клавиши влево - показывался предыдущий месяц, вправо - следующий. На kbhit не реагирует, что я делаю не так? Как это исправить?

Код

/*Задача программы - построить календарь на выбранный месяц выбранного года. 
Кроме месяца и года нам известно, что 1 января 2008 года был вторник и 2008-й год был високосным. 
Единственное, что нам нужно для построения календаря - знать, на какой день недели приходится 
первое число выбранного месяца выбранного года, а также число дней в месяце. 
Собственно, основная задача, возложенная на формулы - получить день недели. Для этого удобно использовать целочисленное деление на 7. 
DaysDist - переменная, в которой я собираюсь получить разницу в днях между 1 января 2008 года и 
1-м числом месяца, для которого я собираюсь строить календарь. Остаток от деления на 7 этой 
разницы и будет днём недели этого самого 1-го числа.
 
 
 
Про iMonth: пользователь вводит месяцы с 1 до 12, а индексация в массиве - с 0 до 11. 
Поэтому чтобы введенное пользователем число преобразовать в индекс массива я вычитаю из него 1
 
  
 
 В зависимости от того, прошлое это или будущее (т.е. DaysDist > 0 или меньше нуля)
  используются два варианта расчёта дня недели. либо это прошлое - DayOfMonth= 7 - (5-DaysDist)%7; либо это будущее - 
  DayOfMonth = (DaysDist+1)%7 + 1;
 
Например, 1 января 2008 года был вторник. значит 365 дней назад был 7 - ( 5 - (-365))%7 = 7 - (370)%7 = 7 - 6 = 1 (понедельник). 
 
Основная мысль календаря в том, что не нужно итеративно высчитывать день недели относительно какого-то там года.
 у нас есть число лет и число месяцев. зная это число лет и число месяцев мы можем в несколько операций умножения 
 и целочисленного деления получить день недели. а формулы могут меняться в зависимости от того, какой день мы берём 
 за отправную точку. я взял 1 января 2008 года, это был вторник (поэтому и формулы малость странные, т.к. 
 не с понедельника начинается отсчёт). 
 
 
*/
 
#include <iostream>
#include <conio.h>
#include <graphics.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
 
 
using namespace std;
 
int DaysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 31 день в январе, 28 в феврале, 31 в марте и т.д.
int DayForw[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; // 0 - начало года, 31 - конец января, 59 - февраля и т.д.
char cMonths[] = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"; // имена месяцев по батюшке
int DaysPerYear = 365; // дней в году
 
int main()
{
    cout << "Enter the month & the year for calendar (mm yyyy): "; // просим ввести месяц и год...
    int iMonth, iYear;
    //int* Direction; 
    cin >> iMonth >> iYear; // записываем в iMonth месяц и в iYear год
    cout << endl;
    int iCorrect, DaysDist; /*DaysDist - переменная, в которой я собираюсь получить разницу в днях между 1 января 2008 года и 
1-м числом месяца, для которого я собираюсь строить календарь. Остаток от деления на 7 этой 
разницы и будет днём недели этого самого 1-го числа.*/
 
    DaysDist = (iYear - 2008);
    //Direction = &DayForw[0]; 
 
    iCorrect = (DaysDist)/4; // запоминаем количество високосных лет, для коррекции дней недели...
    if (DaysDist>0)
        iCorrect++;
    if ((DaysDist)%4 == 0) // если високосный год, то корректируем вспом. массивы...
    {
        if (DaysDist>0)
            iCorrect--;
        for (int i=2; i < 12; i++) // массив для коррекции по месяцу...
            DayForw[i]++;
        DaysPerMonth[1]++; // массив количеств дней в месяце...
    }
    
/*Например, 1 января 2008 года был вторник. значит 365 дней назад был 
7 - ( 5 - (-365))%7 = 7 - (370)%7 = 7 - 6 = 1 (понедельник). */
 
    DaysDist = DaysDist*365+iCorrect+DayForw[iMonth-1]; /* записываем в DaysDist разницу в годах, умножив на 365 получаем 
    разницу в днях. Каждые четыре года набегает один день. Если год меньше 2008-го, то день вычитается каждые четыре года. 
    Например, была разница в -4 года, поэтому -4 * 365 + ( -1 ) + 59 = 1402 дня разницы между 1-м января 2008 года и 
    1 марта 2004 года. iMonth -1, т.к. 12 месяцев от 0 до 11    */
    
    int DayOfMonth;
    if (DaysDist < 0) //Если года в отрицательную сторону от 2008
        DayOfMonth= 7 - (5-DaysDist)%7; // Пятёрка, т.к. вторник второй день недели, 7 - 2 = 5;
    else
        DayOfMonth = (DaysDist+1)%7 + 1; //Если больше 2008
    cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
    cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
    for (int i=1; i<DayOfMonth; i++)
        cout << "\t";
    for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
    {
        cout << "\t" << i+1;
        if (DayOfMonth==7)
        {
            DayOfMonth=0;
            cout << endl << endl;
        }
    }
    cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
    cin >> iYear;
 
 
// НЕ РАБОТАЮЩИЙ КУСОК КОДА ПРЕДСТАВЛЕН НИЖЕ
 
/*
//if (kbhit()) 
while (!_kbhit());
{
  int key = getch(); 
  if (key == 0) key = getch(); 
  switch (key) 
{
         case KEY_RIGHT :
         {
           system("cls");
           iMonth+=1;
           
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
             {
                cout << "\t" << i+1;
                if (DayOfMonth==7)
                {
                 DayOfMonth=0;
                  cout << endl << endl;
                }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
              cin >> iYear; 
             
         }break;
         
         case KEY_LEFT : 
         {
         system("cls");
                     iMonth-=1;
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
             {
                cout << "\t" << i+1;
                if (DayOfMonth==7)
                {
                 DayOfMonth=0;
                  cout << endl << endl;
                }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
              cin >> iYear;     
         }break; 
} 
*/
 
 
    return 0;
}
}

PM   Вверх
feodorv
Дата 3.5.2013, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Честно, не знаю, что за константы такие KEY_RIGHT и KEY_LEFT...

Цитата(zeitgeistz @  3.5.2013,  17:00 Найти цитируемый пост)
while (!_kbhit());

Зачем так извращаться? Пользуйтесь _getch()...
Код

while( (key = _getch()) != 27 )
{
  ...
}



Цитата(zeitgeistz @  3.5.2013,  17:00 Найти цитируемый пост)
 На kbhit не реагирует

Ну так у Вас там:
Цитата(zeitgeistz @  3.5.2013,  17:00 Найти цитируемый пост)
    cin >> iYear;

Сначала этот iYear введите, а уж потом к kbhit приступайте...


По поводу дня недели, можно посмотреть здесь...

Добавлено через 7 минут и 47 секунд
Да, когда iMonth++ или iMonth-- делаете, не забывайте проверять диапазон 1 <= iMonth <= 12 (изменяя год, если нужно)


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 3.5.2013, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Я не заметил, что пишу после 
Код

 cin >> iYear;
 smile

Перед ним написал

Код

if ((key = _getch() ==77) // 77 - стрелка вправо, 75 для стрелки влево

и всё это впихнул в бесконечный цикл
Код

int key;
do {
   /* что-нибудь делаем */
} while(1)

только не знаю как два if'a там примирить, если один if, то работает, если два if'а, то работает какой-то один. что я делаю не так?

Код

do{
if ((key = _getch() ==77)
{
 system("cls");
                     iMonth+=1;
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
             {
                cout << "\t" << i+1;
                if (DayOfMonth==7)
                {
                 DayOfMonth=0;
                  cout << endl << endl;
                }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
}


else if ((key = _getch() ==75)
{
 system("cls");
                     iMonth-=1;
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
             {
                cout << "\t" << i+1;
                if (DayOfMonth==7)
                {
                 DayOfMonth=0;
                  cout << endl << endl;
                }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
}
}while(1);

при таком раскладе: вводим 5 2013, рисуется май, если жмакаем стрелку влево - рисуется апрель, ещё раз влево - март, всё как и надо, но стрелка вправо просто так не работает: нужно нажать enter и потом стрелка вправо сработает, как миновать нажатия enter'а?

Это сообщение отредактировал(а) zeitgeistz - 3.5.2013, 20:01
PM   Вверх
feodorv
Дата 3.5.2013, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(zeitgeistz @  3.5.2013,  20:27 Найти цитируемый пост)
do{
if ((key = _getch() ==77)
  ...
else if ((key = _getch() ==75)
  ...
}
{

Ну это не правильно же... На каждый if свой  _getch()??? Вот и приходится жать, чего не поподя...
Код

do
{
  key = _getch();
  if( key == 0 || key == 0xe0 ) key = _getch();

  if( key == 77 )
    ...
  else if( key == 75 )
    ...
  else if( key == 27 ) // Escape
    break;
}


Добавлено через 3 минуты и 22 секунды
Как насчет
Цитата(feodorv @  3.5.2013,  18:02 Найти цитируемый пост)
Да, когда iMonth++ или iMonth-- делаете, не забывайте проверять диапазон 1 <= iMonth <= 12 (изменяя год, если нужно) 

?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 3.5.2013, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Да, Вы правы, теперь стрелки как положено заработали. Сейчас с годом помудрю и отпишусь минут через 15. Только я так и не понял, почему в том случае приходилось enter нажимать перед стрелкой, в чём дело было?
PM   Вверх
feodorv
Дата 3.5.2013, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(zeitgeistz @  3.5.2013,  21:36 Найти цитируемый пост)
Только я так и не понял, почему в том случае приходилось enter нажимать перед стрелкой, в чём дело было? 

Трудно сказать с уверенностью, поскольку сами стрелки порождают последовательность { 0xe0, 75/77 }, да ещё и в каждый if было запихнуто по _getch()'у (то есть на каждый if нужно было ввести по своему символу)...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 3.5.2013, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



А что такое 0xe0?

Насчёт года, для стрелки влево дописал
Код

         if (iMonth < 0) 
           {
                      iYear-=1;
                      iMonth=12;
           }

для вправо наоборот.

Только для стрелки вправо немного неправильно написал, при переходе на след. год появляется промежуточное пустое окошко с заголовками дней недели, после ещё одной стрелки отрисовывается январь

Как от этого избавиться можно?

Код

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>



using namespace std;

int DaysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 31 день в январе, 28 в феврале, 31 в марте и т.д.
int DayForw[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; // 0 - начало года, 31 - конец января, 59 - февраля и т.д.
char cMonths[] = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"; // имена месяцев по батюшке
int DaysPerYear = 365; // дней в году

int main()
{
    cout << "Enter the month & the year for calendar (mm yyyy): "; // просим ввести месяц и год...
    int iMonth, iYear;
    //int* Direction; 
    cin >> iMonth >> iYear; // записываем в iMonth месяц и в iYear год
    cout << endl;
    int iCorrect, DaysDist; /*DaysDist - переменная, в которой я собираюсь получить разницу в днях между 1 января 2008 года и 
1-м числом месяца, для которого я собираюсь строить календарь. Остаток от деления на 7 этой 
разницы и будет днём недели этого самого 1-го числа.*/

    DaysDist = (iYear - 2008);
    //Direction = &DayForw[0]; 

    iCorrect = (DaysDist)/4; // запоминаем количество високосных лет, для коррекции дней недели...
    if (DaysDist>0)
        iCorrect++;
    if ((DaysDist)%4 == 0) // если високосный год, то корректируем вспом. массивы...
    {
        if (DaysDist>0)
            iCorrect--;
        for (int i=2; i < 12; i++) // массив для коррекции по месяцу...
            DayForw[i]++;
        DaysPerMonth[1]++; // массив количеств дней в месяце...
    }
    
/*Например, 1 января 2008 года был вторник. значит 365 дней назад был 
7 - ( 5 - (-365))%7 = 7 - (370)%7 = 7 - 6 = 1 (понедельник). */

    DaysDist = DaysDist*365+iCorrect+DayForw[iMonth-1]; /* записываем в DaysDist разницу в годах, умножив на 365 получаем 
    разницу в днях. Каждые четыре года набегает один день. Если год меньше 2008-го, то день вычитается каждые четыре года. 
    Например, была разница в -4 года, поэтому -4 * 365 + ( -1 ) + 59 = 1402 дня разницы между 1-м января 2008 года и 
    1 марта 2004 года. iMonth -1, т.к. 12 месяцев от 0 до 11    */
    
    int DayOfMonth;
    if (DaysDist < 0) //Если года в отрицательную сторону от 2008
        DayOfMonth= 7 - (5-DaysDist)%7; // Пятёрка, т.к. вторник второй день недели, 7 - 2 = 5;
    else
        DayOfMonth = (DaysDist+1)%7 + 1; //Если больше 2008
    cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
    cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
    for (int i=1; i<DayOfMonth; i++)
        cout << "\t";
    for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
    {
        cout << "\t" << i+1;
        if (DayOfMonth==7)
        {
            DayOfMonth=0;
            cout << endl << endl;
        }
    }
    cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
 
 
 // ПЕРЕКЛЮЧЕНИЕ СТРЕЛКАМИ
 

    
 int key;
        
        do
{
      key = _getch();
      
      if ( key == 0 || key == 0xe0 ) key = _getch();
                 
            if (key == 77)
           {
           system("cls");
           iMonth+=1;
           if (iMonth > 12) 
           {
                      iYear+=1;
                      iMonth=0;
           }
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
              for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
              for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
              {
                  cout << "\t" << i+1;
                  if (DayOfMonth==7)
                  {
                         DayOfMonth=0;
                         cout << endl << endl;
                  }
               }
           cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
              
}

           else if (key == 75)
{
           system("cls");
           iMonth-=1;
           if (iMonth <= 0) 
           {
                      iYear-=1;
                      iMonth=12;
           }
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;

            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonth[iMonth-1]; DayOfMonth++, i++)
             {
                  cout << "\t" << i+1;
                  if (DayOfMonth==7)
                  {
                         DayOfMonth=0;
                         cout << endl << endl;
                  }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
              
}

}while(1);
             


    cin >> iYear;
    return 0;
}


Это сообщение отредактировал(а) zeitgeistz - 3.5.2013, 21:20
PM   Вверх
feodorv
Дата 3.5.2013, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(zeitgeistz @  3.5.2013,  22:07 Найти цитируемый пост)
         if (iMonth < -1) 

Цитата(zeitgeistz @  3.5.2013,  22:07 Найти цитируемый пост)
i<DaysPerMonth[iMonth-1]

Ну если уже значение 0 неприемлемо для iMonth, то почему if (iMonth < -1)???
Код

if( iMonth <= 0 ) ...


Посмотрел начало кода:
Цитата(zeitgeistz @  3.5.2013,  22:07 Найти цитируемый пост)
    if ((DaysDist)%4 == 0) // если високосный год, то корректируем вспом. массивы...
    {
        if (DaysDist>0)
            iCorrect--;
        for (int i=2; i < 12; i++) // массив для коррекции по месяцу...
            DayForw[i]++;
        DaysPerMonth[1]++; // массив количеств дней в месяце...
    }

Это в корне не верно, если Вы собираетесь показывать календарь и для другого года. У Вас должны быть два набора неизменяемых массивов - для невисокосного года и отдельно для високосного.
Соответственно, когда год меняется, нужно определить подходящий набор.

Потом. Високосность не определяется простым делением на 4 (например, 1900 год не был високосным), правило сложнее


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 3.5.2013, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Там для стрелки влево я ещё до Вашего ответа отредактировал, вправо стрелка не так работает, давайте с этим разберёмся, а потом за високосный возьмёмся
PM   Вверх
zeitgeistz
Дата 3.5.2013, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Ну чевой там, есть идеи?
PM   Вверх
feodorv
Дата 3.5.2013, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Ну совершенно аналогично:
Цитата(zeitgeistz @  3.5.2013,  22:07 Найти цитируемый пост)
                      iMonth=0;

Почему 0? Ведь месяцы начинаем отсчитывать от 1...

Добавлено через 35 секунд
Цитата(zeitgeistz @  3.5.2013,  23:02 Найти цитируемый пост)
Ну чевой там, есть идеи? 

Да, лечь спать)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 3.5.2013, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



Ай спасибо большое! Заработало как надо!
Рано ещё спать, високосные криво работают smile Попробовал правильную формулу адаптировать сюда

Код

#include <iostream>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>


using namespace std;

int DaysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int DayForw[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 
int DayPerMonthLeap[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
int DayForwLeap[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
char cMonths[] = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"; 
int DaysPerYear = 365; 
int* DaysPerMonthUniversal = DaysPerMonth;
int* DayForwUniversal =  DayForw;


int main()
{
    cout << "Enter the month & the year for calendar (mm yyyy): "; 
    int iMonth, iYear;

    cin >> iMonth >> iYear; 
    if (iMonth > 12)
    {
               do{
               system ("cls");
               cout << "Month incorrect! \n\nEnter the month & the year for calendar (mm yyyy): ";
               cin >> iMonth >> iYear;
               }while(iMonth > 12 || iMonth == 0 || iMonth <1) ;
    }
    else cout << endl;
    
    int iCorrect, DaysDist; 
    DaysDist = (iYear - 2008);

    iCorrect = (DaysDist)/4; 
    if (DaysDist>0)
        iCorrect++;
    if    ((((DaysDist)  % 4)  == 0)  &&    (((DaysDist)  % 100)  != 0)  ||   (((DaysDist)  % 400)  == 0)) 
    {
        if (DaysDist>0)
            iCorrect--;
        DaysPerMonthUniversal = DayPerMonthLeap;
        DayForwUniversal =  DayForwLeap;
    }


    DaysDist = DaysDist*365+iCorrect+DayForw[iMonth-1]; 
    
    
    int DayOfMonth;
    if (DaysDist < 0) 
        DayOfMonth= 7 - (5-DaysDist)%7; 
    else
        DayOfMonth = (DaysDist+1)%7 + 1; 
    cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
    cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
    for (int i=1; i<DayOfMonth; i++)
        cout << "\t";
    for (int i=0; i<DaysPerMonthUniversal[iMonth-1]; DayOfMonth++, i++)
    {
        cout << "\t" << i+1;
        if (DayOfMonth==7)
        {
            DayOfMonth=0;
            cout << endl << endl;
        }
    }
    cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
 
 

 

    
 int key;
        
        do
{
      key = _getch();
      
      if ( key == 0 || key == 0xe0 ) key = _getch();
                 
            if (key == 77) // Right
           {
           system("cls");
           iMonth+=1;
           if (iMonth > 12) 
           {
                      iYear+=1;
                      iMonth=1;
           }
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;
              for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
              for (int i=0; i<DaysPerMonthUniversal[iMonth-1]; DayOfMonth++, i++)
              {
                  cout << "\t" << i+1;
                  if (DayOfMonth==7)
                  {
                         DayOfMonth=0;
                         cout << endl << endl;
                  }
               }
           cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;
              
}

           else if (key == 75) // Left
{
           system("cls");
           iMonth-=1;

           DaysDist = (iYear - 2008);

    iCorrect = (DaysDist)/4; 
    if (DaysDist>0)
        iCorrect++;
    if ((((DaysDist)  % 4)  == 0)  &&    (((DaysDist)  % 100)  != 0)  ||   (((DaysDist)  % 400)  == 0))
    {
        if (DaysDist>0)
            iCorrect--;
        DaysPerMonthUniversal = DayPerMonthLeap;
        DayForwUniversal =  DayForwLeap;
    }


    DaysDist = DaysDist*365+iCorrect+DayForw[iMonth-1]; 
    }

    DaysDist = DaysDist*365+iCorrect+DayForw[iMonth-1];
           if (DaysDist < 0) 
                     DayOfMonth= 7 - (5-DaysDist)%7; 
           else
                     DayOfMonth = (DaysDist+1)%7 +1;
       
           if (iMonth <= 0) 
           {
                      iYear-=1;
                      iMonth=12;
           }
           cout << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl << endl;
           cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;

            for (int i=1; i<DayOfMonth; i++)
                  cout << "\t";
            for (int i=0; i<DaysPerMonthUniversal[iMonth-1]; DayOfMonth++, i++)
             {
                  cout << "\t" << i+1;
                  if (DayOfMonth==7)
                  {
                         DayOfMonth=0;
                         cout << endl << endl;
                  }
             }
              cout << endl << endl << "\t    ************ " << cMonths+(iMonth-1)*4 << " " << iYear << " ************" << endl;

}while(1);
             


    cin >> iYear;
    return 0;
}
Откомпилируйте у себя, что тут не так, что исправить? Помогите, пожалуйста

Это сообщение отредактировал(а) zeitgeistz - 4.5.2013, 14:00
PM   Вверх
zeitgeistz
Дата 4.5.2013, 12:23 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



up
PM   Вверх
feodorv
Дата 4.5.2013, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Гм. Я бы поправил всё)))) Первым делом - оформление кода. Вторым - ввёл бы подпрограмму отрисовки месяца календаря:
Код

void showMonth( int month, int year)
{
  int weekDay = dayOfWeek( month, year);
  int dayMax = isLeapYear(year) ? DayPerMonthLeap[month-1] : DaysPerMonth[month-1];
  int day;

  system( "cls" );
  cout << "\t    ************ " << &cMonths[(month-1)*4] << " " << year << " ************" << endl << endl;
  cout << "\tMon\tTue\tWed\tThu\tFri\tSat\tSun" << endl << endl;

  for( day = 1; day < weekDay; day++) cout << "\t";

  for( day = 0; day < dayMax; weekDay++, day++)
  {
      cout << "\t" << day+1;
      if( weekDay == 7 )
      {
          weekDay = 0;
          cout << endl << endl;
      }
  }

  cout << endl << endl << "\t    ************ " << &cMonths[(month-1)*4] << " " << year << " ************" << endl;
}

Тогда программа значительно упроститься и приобретёт более благородный вид. Например:
Код

  do
  {
     int key = _getch();
     if( key == 0 || key == 0xe0 ) key = _getch();
                 
     if( key == 77 )
     {
        if( ++month > 12 )
        {
           month = 1;
           ++year;
        }
        showMonth( month, year);
     }
     else if( key == 75 )
     {
        if( month == 1 )
        {
           if( year > 1 )
           {
              month = 12;
              --year;
           }
        }
        else
           --month;
        showMonth( month, year);
     }
     else if( key == '\r' )
     {
        enterYearMonth( &month, &year);
        showMonth( month, year);
     }
     else if( key == 27 )
        break;
  } while(1);


В-третих, я бы поправил определение дня недели у текущего месяца - оно делается неверно: два смежных месяца не стыкуются друг с другом по дням недели. То есть написал бы dayOfWeek для произвольного месяца-года.

В-четвёртых, я бы сразу показывал бы текущий месяц, а ввод произвольного месяца-года убрал бы внутрь цикла.

Править текущий код я не могу - ничего в нём не понимаю)))

Это сообщение отредактировал(а) feodorv - 4.5.2013, 14:38


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
zeitgeistz
Дата 4.5.2013, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 36
Регистрация: 23.4.2013

Репутация: нет
Всего: нет



А как isLeapYear будет выглядеть?
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0648 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.