How to create a C Calendar?

Asked

Viewed 1,092 times

-1

I need to elaborate an algorithm that writes the calendar in the following format: inserir a descrição da imagem aqui

I’m testing at 2 months but I can’t maintain lateral alignment. My code is that way:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int i; //mes
int j; //dia
int cont = 0; //quebra linha
int ano, mes, dia, bis;
int g, c, x, z, e, d, n;
int mesDias[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char *months[]=
{
    "Janeiro",
    "Fevereiro",
    "Marco",
    "Abril",
    "Maio\t",
    "Junho",
    "Julho",
    "Agosto",
    "Setembro",
    "Outubro",
    "Novembro",
    "Dezembro"
};

int main(int argc, char *argv[]) {
    printf("Digite o ano: ");
    scanf("%d", &ano);


    //P A S C O A

    g = (ano % 19) + 1; //resto inteiro - AUREO
    c = (ano / 100) + 1; //SECULO
    x = ((3 * c) / 4) - 12; //CORRECAO 1
    z = (((8 * c) + 5) / 25) - 5; //CORRECAO 2
    e = ((11 * g) + 20 + z - x) % 30; //resto inteiro

    //EPACTA
    if(e == 25 && g > 11){
        e++;
    }
    else if(e == 24){
        e++;
    }

    //LUA CHEIA
    n = 44 - e; 
    if(n < 21){
        n += 30;
    }

    //DOMINGO DE PASCOA
    d = ((5 * ano) / 4) - (x + 10);


    //DIA/MES PASCOA
    n = (n + 7) - ((d + n) % 7);

    if(n > 31){
        n = n - 31;
        printf("Pascoa: %d de abril", n);
        mes = 4;
    }
    else{
        printf("Pascoa: %d de marco", n);
        mes = 3;
    }

    // B I S S E X T O

    if (ano % 4 == 0 && (ano % 400 == 0 || ano % 100 != 0)) {
        printf("\nAno bissexto.");
        bis = 1;
        mesDias[1] = 29;
    }
    else {
        printf("\nAno nao bissexto.");
        bis = 0;
    }


    //1   D E    J A N E I R O
    if(mes == 4){
        dia = 8 - ((n + bis + 31 + 28 + 31 ) % 7) ; 
    }
    else if(mes == 3){
        dia = 8 - ((n + bis + 31 + 28) % 7) ;
    }
    if(dia > 6) dia -= 7;

    dia++;

    if(dia == 1){
        printf("\n1 de jan: domingo\n");
    }else if(dia == 2){
        printf("\n1 de jan: segunda\n");
    }else if(dia == 3){
        printf("\n1 de jan: terca\n");
    }else if(dia == 4){
        printf("\n1 de jan: quarta\n");
    }else if(dia == 5){
        printf("\n1 de jan: quinta\n");
    }else if(dia == 6){
        printf("\n1 de jan: sexta\n");
    }else if(dia == 7){
        printf("\n1 de jan: sabado\n");
    }

    printf("\n\n");


    /*CALENDÁRIO*/

    printf("Calendario do ano %d\n", ano);

    printf("|-----------------------------|\n");
    for(i = 0; i < 2; i++){

    printf("|%s\t\t      |\n", months[i]);
    printf("| dom seg ter qua qui sex sab |\n");
    printf("|");
    printf("  ");

    /*pular dias vazios*/
    if(i == 0){
        for ( j = 0; j < dia - 1; j++ ){
            printf("--  ");
            cont++;
        }
    }else{
        if(dia != 0){
            for ( j = 0; j < dia - 1; j++ ){
                printf("--  ");
                cont++;
            }
        }else{
            for ( j = -1; j < dia - 1; j++ ){
                printf("--  ");
                cont++;
            }   
        }

        printf("--  ");
    }


    /*escrever meses do dia*/
    for(j = 1; j < mesDias[i] + 1; j++){

        if(j <= 9){

            if(cont >= 6){
                printf(" %d |\n|  ", j);
                cont = 0;
            }else{
                printf(" %d  ", j);
                cont++;
            }


        }else{
            if(j == 10){
                printf("%d", j);
                cont++;
            }else{
                printf("  %d", j);
                cont++;
            }           

            if(cont > 6){
                printf(" |\n|");
                cont = 0;
            }
        }

        if(cont > 6){
            printf("\n|  ");
            cont = 0;
        }

    }
    printf("\n");
    dia = cont;

    printf("\ndia: %d\n", dia);

    }

            return 0;
}

2 answers

0

First, to display the month name with alignment, do not use \t. Enjoy the options that printf gives you:

char *months[]=
{
    "Janeiro",
    "Fevereiro",
    "Marco",
    "Abril",
    "Maio", // <-- removi o \t daqui
    "Junho",
    "Julho",
    "Agosto",
    "Setembro",
    "Outubro",
    "Novembro",
    "Dezembro"
};

...
printf("|%-29s|\n", months[i]);

The format %-29s says to align left, occupying 29 positions (positions that are not used are filled with spaces). So you are not depending on \t and other mischief, the printf already takes care of the alignment for you.


Already to print the days of the month, you are complicating the logic aimlessly. You can do so:

printf("Calendario do ano %d\n", ano);
for (i = 0; i < 12; i++) { // para cada mês
    int diaDaSemana = 0; // começa sempre a imprimir do domingo

    printf("|-----------------------------|\n");
    printf("|%-29s|\n", months[i]);
    printf("|-----------------------------|\n");
    printf("| dom seg ter qua qui sex sab |\n");
    printf("|");

    int linhasImpressas = 1; // quantidade de linhas que já foram impressas

    // pular dias vazios do início do mês
    for (j = 0; j < dia - 1; j++) {
        printf("  --");
        diaDaSemana++;
    }

    // dias do mês
    for (int diaDoMes = 1; diaDoMes <= mesDias[i]; diaDoMes++) {
        printf("  %02d", diaDoMes);
        if (diaDaSemana >= 6) { // chegou no sábado, começar nova linha
            printf(" |\n|");
            diaDaSemana = 0;
            linhasImpressas++;
        } else diaDaSemana++;
    }
    dia = diaDaSemana + 1;

    if (linhasImpressas == 5) {    
        // preencher o que falta na quinta linha
        while (diaDaSemana <= 6) {
            printf("  --");
            diaDaSemana++;
        }
        // imprimir a sexta linha
        printf(" |\n|  --  --  --  --  --  --  -- |\n");
    } else if (linhasImpressas == 6) {
        // preencher o que falta na sexta linha
        for (int x = dia - 1; x <= 6; x++)
            printf("  --");
        printf(" |\n");
    }
}

That is, first I fill out the empty days of the beginning of the month. Then I fill in the days using the format %02d that prints the number with a zero on the left if necessary.

Then I check if I am in the fifth or sixth row (from what I understand, every month must have 6 lines), and fill in what is missing in each case.

Output example for year 2020:

Calendario do ano 2020
|-----------------------------|
|Janeiro                      |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  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  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Fevereiro                    |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  --  --  --  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 |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Marco                        |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  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  --  --  --  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Abril                        |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  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  --  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Maio                         |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  --  --  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  --  --  --  --  --  -- |
|-----------------------------|
|Junho                        |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  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  --  --  --  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Julho                        |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  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  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Agosto                       |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  --  --  --  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  --  --  --  --  -- |
|-----------------------------|
|Setembro                     |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  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  --  --  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Outubro                      |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  --  --  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 |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Novembro                     |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  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  --  --  --  --  -- |
|  --  --  --  --  --  --  -- |
|-----------------------------|
|Dezembro                     |
|-----------------------------|
| dom seg ter qua qui sex sab |
|  --  --  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  --  -- |
|  --  --  --  --  --  --  -- |

Of course we can still improve other things, such as giving better names to variables. Instead of i and j, could be mesAtual and diaDoMes, or something like that, and the variable dia could be something like primeiroDiaSemana (or any other name indicating that it refers to the day of the week corresponding to the first day of the month). It may sound silly, but giving better names helps a lot when programming.

The for printing days of the month could also be:

for (int diaDoMes = 1; diaDoMes <= mesDias[i]; diaDoMes++) {
    printf("  %02d", diaDoMes);
    if (diaDaSemana == 6) {
        printf(" |\n|");
        linhasImpressas++;
    }
    diaDaSemana = (diaDaSemana + 1) % 7;
}

The operator % takes the rest of the split. Then when the value of diaDaSemana + 1 becomes 7, it returns to zero (because the rest of the division of 7 by 7 is zero). Thus, the count goes back to the initial value every 7 iterations. And the test can be diaDaSemana == 6 (how I initialize it with zero at the beginning of for outside, and always get the rest of the division by 7, I know it won’t be bigger than 6).

-1

If you are running on a Unix machine Like creoq that you can use the shell cal command ai your code would look like this

 #include <stdlib.h> // para incluir o system

    int main(void) {
      system("cal 1");
    } // cal 1 para chamar o cal shell 

The way out will be is:

                             1
      Janeiro              Fevereiro               Março          
do se te qu qu se sá  do se te qu qu se sá  do se te qu qu se sá  
                   1         1  2  3  4  5         1  2  3  4  5  
 2  3  4  5  6  7  8   6  7  8  9 10 11 12   6  7  8  9 10 11 12  
 9 10 11 12 13 14 15  13 14 15 16 17 18 19  13 14 15 16 17 18 19  
16 17 18 19 20 21 22  20 21 22 23 24 25 26  20 21 22 23 24 25 26  
23 24 25 26 27 28 29  27 28                 27 28 29 30 31        
30 31                                                             

       Abril                  Maio                 Junho          
do se te qu qu se sá  do se te qu qu se sá  do se te qu qu se sá  
                1  2   1  2  3  4  5  6  7            1  2  3  4  
 3  4  5  6  7  8  9   8  9 10 11 12 13 14   5  6  7  8  9 10 11  
10 11 12 13 14 15 16  15 16 17 18 19 20 21  12 13 14 15 16 17 18  
17 18 19 20 21 22 23  22 23 24 25 26 27 28  19 20 21 22 23 24 25  
24 25 26 27 28 29 30  29 30 31              26 27 28 29 30        


       Julho                 Agosto               Setembro        
do se te qu qu se sá  do se te qu qu se sá  do se te qu qu se sá  
                1  2      1  2  3  4  5  6               1  2  3  
 3  4  5  6  7  8  9   7  8  9 10 11 12 13   4  5  6  7  8  9 10  
10 11 12 13 14 15 16  14 15 16 17 18 19 20  11 12 13 14 15 16 17  
17 18 19 20 21 22 23  21 22 23 24 25 26 27  18 19 20 21 22 23 24  
24 25 26 27 28 29 30  28 29 30 31           25 26 27 28 29 30     
31                                                                

      Outubro               Novembro              Dezembro        
do se te qu qu se sá  do se te qu qu se sá  do se te qu qu se sá  
                   1         1  2  3  4  5               1  2  3  
 2  3  4  5  6  7  8   6  7  8  9 10 11 12   4  5  6  7  8  9 10  
 9 10 11 12 13 14 15  13 14 15 16 17 18 19  11 12 13 14 15 16 17  
16 17 18 19 20 21 22  20 21 22 23 24 25 26  18 19 20 21 22 23 24  
23 24 25 26 27 28 29  27 28 29 30           25 26 27 28 29 30 31  
30 31        
  • Unfortunately I can not use this way, I have to use the calculations of the day of March and first of January, and from there print all dates manually.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.