Как я могу печатать даты в нужные дни недели? - PullRequest
0 голосов
/ 24 апреля 2020
#include <stdio.h>
#include <math.h>
.
.
.
void calendar(int year, int month){

    int days, wd;

    puts("===================================================");
    printf("                      %c%c%c/%d\n",month_str[month][0],month_str[month][1],month_str[month][2],year);
    puts("\nSUN     MON     TUE     WED     THU     FRI     SAT");

    if(month == 2)
    {
        if(isLeap(year)==1)
            days = 29;
        if(isLeap(year)==0)
            days = 28;
    }
    else
        days = days_in_months[month];

// i need to correct this part
    //print dates
    for (int d = 1; d <= 1 + weekDay(year,month,d) * 5; d++ )
        {
            printf("    ");
        }
    for (int i = 1; i <=days; i++)
    {
       wd = weekDay(year,month, i);
       printf("%.2d",i);

       if ((wd+1) % 7 == 0)
            printf("\n");
        else
            printf("      ");    
    }
    puts("\n===================================================");
}

Когда я ввожу 2/2015, это дает бесконечность l oop. (Теперь у меня нет проблем с бесконечностью l oop)

Пример: Ввод: 2 2020 | Выход:

===================================================
                    FEB/2020
SUN     MON     TUE     WED     THU     FRI     SAT
--      --      --      --      --      --      01
02      03      04      05      06      07      08
09      10      11      12      13      14      15
16      17      18      19      20      21      22
23      24      25      26      27      28      29
===================================================

Вход: 02 2015 | Вывод:

===================================================
                      APR/2020

SUN     MON     TUE     WED     THU     FRI     SAT
--      --      --      01      02      03      04
05      06      07      08      09      10      11
12      13      14      15      16      17      18
19      20      21      22      23      24      25
26      27      28      29      30      --      --      
===================================================

У меня проблемы только с выводом

Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее, Подробнее

1 Ответ

2 голосов
/ 24 апреля 2020

Если я что-то не так понимаю, единственное, что вас беспокоит, это как выровнять первую неполную неделю чисел под заголовками дней недели. Поскольку первый день каждого месяца является первым, вы можете просто сконцентрироваться на weekDay(year,month,1).

Кроме того, поскольку все дни разделены 8 символами (один нормальный tab ширина), вы можете просто вставьте 8 пробелов для каждого смещения дня недели. Таким образом, вам необходимо добавить первый день для общего числа пробелов:

padding = weekDay(year,month,1) * 8;

Это позволяет вам исключить l oop и просто использовать field-width модификатор, который устанавливается padding в качестве первого аргумента на printf при выводе пробела, например

       int days, wd, padding;     /* add padding variable */
       ...

//     for (int d = 1; d <= 1 + weekDay(year,month,d) * 5; d++)
//     {
//         printf("    ");
//     }
    if ((padding = weekDay(year,month,1) * 8))
        printf ("%*s", padding, " ");

Или после вычисления padding вы можете просто l oop это количество раз выводить пробелы Например,

    padding = weekDay(year,month,1) * 8;
    while (padding--)
        putchar (' ');

Тот же результат в любом случае.

Пример Использование / Вывод

Это похоже на то, что вы пытаетесь, например

за март 2020 года

$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
                      MAR/20

SUN     MON     TUE     WED     THU     FRI     SAT
01      02      03      04      05      06      07
08      09      10      11      12      13      14
15      16      17      18      19      20      21
22      23      24      25      26      27      28
29      30      31
===================================================

за апрель 2020 года:

$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
                      APR/20

SUN     MON     TUE     WED     THU     FRI     SAT
                        01      02      03      04
05      06      07      08      09      10      11
12      13      14      15      16      17      18
19      20      21      22      23      24      25
26      27      28      29      30
===================================================

за май 2020 года:

$ ./bin/calendar
enter mm yyyy : 5 2020
===================================================
                      MAY/20

SUN     MON     TUE     WED     THU     FRI     SAT
                                        01      02
03      04      05      06      07      08      09
10      11      12      13      14      15      16
17      18      19      20      21      22      23
24      25      26      27      28      29      30
31
===================================================

Добавление заполнителей в начале и в конце

Если вы хотите добавить "-- " заполнители для пустых дат, то для добавления заполнителей в начале вы можете просто l oop столько раз заполнять с полной строкой, например,

    padding = weekDay(year,month,1);
    while (padding--)
        fputs ("--      ", stdout);

И в конце, пересчитать заполнение от последнего дня до конца, например,

* 104 6 *

Пример использования / вывода

С заполнителем вы получите:

Фев, 2020:

$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
                      FEB/20

SUN     MON     TUE     WED     THU     FRI     SAT
--      --      01      02      03      04      05
06      07      08      09      10      11      12
13      14      15      16      17      18      19
20      21      22      23      24      25      26
27      28      29      --      --      --      --
===================================================

Март, 2020:

$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
                      MAR/20

SUN     MON     TUE     WED     THU     FRI     SAT
01      02      03      04      05      06      07
08      09      10      11      12      13      14
15      16      17      18      19      20      21
22      23      24      25      26      27      28
29      30      31      --      --      --      --
===================================================

Апрель, 2020:

$ ./bin/calendar
enter mm yyyy : 4 2020
===================================================
                      APR/20

SUN     MON     TUE     WED     THU     FRI     SAT
--      --      --      01      02      03      04
05      06      07      08      09      10      11
12      13      14      15      16      17      18
19      20      21      22      23      24      25
26      27      28      29      30      --      --
===================================================

То, что проверка по моему календарю кажется правильной. Полный код, который я использовал для проверки:

( обновлено: исправлено weekDay() расчет)

#include <stdio.h>
#include <math.h>

const char weekday_str[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
const char month_str[13][4] = {"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN","JUL", 
                                "AGO", "SEP", "OCT", "NOV", "DEC"};
const int days_in_months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int weekDay (int yr, int mh, int d)
{
    int y, c, m, w;

    if (mh == 1 || mh == 2)
        yr--;

    y = yr % 100;
    c = (yr - y) / 100;

    if (mh == 1 || mh == 2)
        m = mh + 10;
    else if (mh <= 12 || mh >= 3)
        m = mh - 2;

    w = ((d + floor(2.6*m - 0.2) + y + floor(0.25*y) + floor(0.25*c) - 2*c ));
    w = w % 7;

    if(w < 0)
        w += 7;

    return w;
}

int isLeap (int year)
{
    if (year%4 != 0)
        return 0;
    else if (year%100 != 0)
        return 1;
    else if (year%400 != 0)
        return 0;
    else
        return 1;
}

void calendar (int year, int month)
{
    int days, wd, padding;

    puts ("===================================================");
    printf ("                      %c%c%c/%d\n",
            month_str[month][0],month_str[month][1],month_str[month][2],year);
    puts ("\nSUN     MON     TUE     WED     THU     FRI     SAT");

    if (month == 2) {
        if (isLeap(year) == 1)
            days = 29;
        if (isLeap(year) == 0)
            days = 28;
    }
    else
        days = days_in_months[month];

    padding = weekDay(year,month,1);
    while (padding--)
        fputs ("--      ", stdout);

    for (int i = 0; i < days; i++) {
        wd = weekDay(year,month, i + 1);
        printf("%.2d", i + 1);

        if ((wd+1) % 7 == 0)
            printf("\n");
        else
            printf("      ");    
    }

    padding = 7 - weekDay(year,month,days) - 1;
    while (padding--)
        fputs ("--      ", stdout);

    puts("\n===================================================");
}

int main (void) {

    int mm, yyyy;

    fputs ("enter mm yyyy : ", stdout);
    if (scanf ("%d %*c%d", &mm, &yyyy) != 2) {
        fputs ("error: invalid format.\n", stderr);
        return 1;
    }

    calendar (yyyy, mm);
} 

Invalid weekDay() Расчет

Проблема с календарем на январь или февраль заключается в неправильной настройке m = mh; У вас есть:

    if (mh == 1 || mh == 2)
        m = mh + 10;
    if (mh <= 12 || mh >= 3)
        m = mh - 2;

Вам нужно:

    if (mh == 1 || mh == 2)
        m = mh + 10;
    else if (mh <= 12 || mh >= 3)
        m = mh - 2;

Причина: после того, как вы отрегулируете Jan или Feb как m = mh + 10;, вы проверяете снова, if (mh <= 12 || mh >= 3), что теперь верно, поскольку вы только что добавили + 10, поэтому вы делаете m = mh - 2, что приводит к неправильному значению для mh.

Пример использования / Вывод

за январь 2020 года

$ ./bin/calendar
enter mm yyyy : 1 2020
===================================================
                      JAN/20

SUN     MON     TUE     WED     THU     FRI     SAT
--      --      --      01      02      03      04
05      06      07      08      09      10      11
12      13      14      15      16      17      18
19      20      21      22      23      24      25
26      27      28      29      30      31      --
===================================================

за февраль 2020 года

$ ./bin/calendar
enter mm yyyy : 2 2020
===================================================
                      FEB/20

SUN     MON     TUE     WED     THU     FRI     SAT
--      --      --      --      --      --      01
02      03      04      05      06      07      08
09      10      11      12      13      14      15
16      17      18      19      20      21      22
23      24      25      26      27      28      29

===================================================

за март , 2020

$ ./bin/calendar
enter mm yyyy : 3 2020
===================================================
                      MAR/20

SUN     MON     TUE     WED     THU     FRI     SAT
01      02      03      04      05      06      07
08      09      10      11      12      13      14
15      16      17      18      19      20      21
22      23      24      25      26      27      28
29      30      31      --      --      --      --
===================================================

Дайте мне знать, если у вас есть какие-либо вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...