Ir ao conteúdo
  • Cadastre-se

C calendario em c matriz


marvelous12

Posts recomendados

preciso fazer um calendario que calcule o primeiro de janeiro a a partir da data do primeiro de janeiro, mas estou com dificuldade pois tenho que  printar na tela como matriz com 6 linhas 2 duas colunas mas so consigo printar as primeira linha  com janeiro e fevereiro,pfv quem puder ajuda me ajuda

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

int i; //mes
int j; //dia
int k;
int data;
int cont = 0; //quebra linha
int ano, mes, dia, bis, bar, linhaCalendario, inicioMes;
int diasMes;
int dias_esq = 0;
int dias_dir = 1;


int g, c, x, z, e, d, n,m;
int inicioMes;
int mesDias[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char *meses[12] =
    {
        "Janeiro",
        "Fevereiro",
        "Marco",
        "Abril",
        "Maio",
        "Junho",
        "Julho",
        "Agosto",
        "Setembro",
        "Outubro",
        "Novembro",
        "Dezembro"};
        
int janeiro_dias[] = 
{
     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
};

int fevereiro_dias[] = 
{
     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
};
int marco_dias[] = 
{
     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
};
int abril_dias[] = 
{
     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
};
int maio_dias[] = 
{
     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
};
int junho_dias[] = 
{
     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
};
int julho_dias[] = 
{
     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
};
int agosto_dias[] = 
{
     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
};
int setembro_dias[] = 
{
     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
};
int outubro_dias[] = 
{
     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
};
int novembro_dias[] = 
{
     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
};
int dezembro_dias[] = 
{
     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
};



int main()
{
    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;           //correção 1
    z = (((8 * c) + 5) / 25) - 5;     //correção 2
    e = ((11 * g) + 20 + z - x) % 30; //resto inteiro

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

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

    //DOMINGO DE PASCOA fa?a N = 44 - E. Se N < 21,
    d = ((5 * ano) / 4) - (x + 10);
    data = (n + 7) - ((d + n) % 7);

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

    int y = ano;

    if (y % 100 == 0)
    {
        y = y / 100;
    }

    printf("%d\n", y);
    if (y % 4 == 0)
    {
        printf("bissexto\n");
    }
    else
    {
        printf("nao e bissexto\n");
    }
    
        printf("Calendario do ano %d\n", ano);
        printf("\n|-----------------------------||-----------------------------|\n");
    
        printf("|%-29s||%-29s|", meses[0], meses[1]);
    
        printf("\n|-----------------------------||-----------------------------|");
        printf("\n| dom seg ter qua qui sex sab || dom seg ter qua qui sex sab |\n|");

    // Esse primeiro for roda 5 vezes. Pois o calend�rio possui 5 linhas.
    
    for (int i = 0; i < 5; i++)
    {   
        
        int control_dir = 3;
        // Este for abaixo � para imprimir os meses da coluna � esquerda.
        // Ele roda 35 vezes, pois em um calend�rio existem 35 espa�os (7 dias x 5 linhas = 35 espa�os)
        for (; dias_esq < 35; dias_esq++)
        {
            
            // A cada 7 dias, imprime duas barras || e pula para o proximo for, atrav�s do comando break
            if(dias_esq == 6 || dias_esq == 13 || dias_esq == 20 || dias_esq == 27)
            {
                printf("  %.2d", janeiro_dias[dias_esq - control_dir]);
                printf(" ||");
                dias_esq++;
                break; // O pr�ximo for vai ser executado, imprimindo agora os dias da coluna � direita
            }
            else if (dias_esq >= 34)
            {
                printf("  -- ||");
            }
            else if (dias_esq > (30 + control_dir) || dias_esq <= (control_dir - 1))
            {
                printf("  --");
            }
            else
            {
                printf("  %.2d", marco_dias[dias_esq - control_dir]);
            }
        }

        int control = 6;
        // Este for abaixo � para imprimir os meses da coluna � direita.
        for (; dias_dir <= 35; dias_dir++)
        {
            if (dias_dir > (28 + control) || dias_dir <= control)
            {
                printf("  --");
            }
            else
            {
                printf("  %.2d", abril_dias[dias_dir - (1 + control)]);
            }

            // A cada 7 dias, imprime uma barra, uma quebra de linha e outra barra e pula para o proximo for, atrav�s do comando break
            if (dias_dir % 7 == 0)
            //if(dias_esq == 6)
            {   

                // Ele s� faz isso at� a pen�ltima linha, pois a �ltima n�o precisa de uma quebra de linha
                if (i < 4)
                {
                    printf(" |\n|");
                }

                dias_dir++; 

                break; // Realiza o break, voltando para o primeiro For. E assim sucessivamente...
          
           }
        
            
        }
        
        
        
    }
    
     for (int m = 0; m < 5; m++)
    {   
        
        int control_dir = 3;
        // Este for abaixo � para imprimir os meses da coluna � esquerda.
        // Ele roda 35 vezes, pois em um calend�rio existem 35 espa�os (7 dias x 5 linhas = 35 espa�os)
        for (; dias_esq < 35; dias_esq++)
        {
            
            // A cada 7 dias, imprime duas barras || e pula para o proximo for, atrav�s do comando break
            if(dias_esq == 6 || dias_esq == 13 || dias_esq == 20 || dias_esq == 27)
            {
                printf("  %.2d", marco_dias[dias_esq - control_dir]);
                printf(" ||");
                dias_esq++;
                break; // O pr�ximo for vai ser executado, imprimindo agora os dias da coluna � direita
            }
            else if (dias_esq >= 34)
            {
                printf("  -- ||");
            }
            else if (dias_esq > (30 + control_dir) || dias_esq <= (control_dir - 1))
            {
                printf("  --");
            }
            else
            {
                printf("  %.2d", marco_dias[dias_esq - control_dir]);
            }
        }

        int control = 6;
        // Este for abaixo � para imprimir os meses da coluna � direita.
        for (; dias_dir <= 35; dias_dir++)
        {
            if (dias_dir > (28 + control) || dias_dir <= control)
            {
                printf("  --");
            }
            else
            {
                printf("  %.2d", maio_dias[dias_dir - (1 + control)]);
            }

            // A cada 7 dias, imprime uma barra, uma quebra de linha e outra barra e pula para o proximo for, atrav�s do comando break
            if (dias_dir % 7 == 0)
            //if(dias_esq == 6)
            {   

                // Ele s� faz isso at� a pen�ltima linha, pois a �ltima n�o precisa de uma quebra de linha
                if (i < 4)
                {
                    printf(" |\n|");
                }

                dias_dir++; 

                break; // Realiza o break, voltando para o primeiro For. E assim sucessivamente...
          
           }
        
            
        }
        
        
        
    }
    
    

    printf(" |\n|  --  --  --  --  --  --  -- ||  --  --  --  --  --  --  -- |\n"); 
    return 0;

}

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

 

Tem lido os posts no tópico que você mesmo postou?

 

Tem muitas coisas lá. No tópico #9 por exemplo eu postei um programa que converte isso em QUALQUER NÚMERO DE COLUNAS. Duas, por exemplo.

 

Em seu programa criou 12 vetores praticamente idênticos. Acha que precisava mesmo disso? E entende que o fato de pegar os meses e por lado a lado nada tem a ver com o calendário? Podia ser qualquer coisa.
 

Exemplo

(A)
(B)
(C)
(D)
(E)
(F)

Em duas colunas se o "mês" tivesse 3 linhas?

(A)(D)
(B)(E)
(C)(F)

Sugiro ler os posts lá no outro tópico.

 

Porque abriu outro tópico sobre o mesmo exato problema 5 dias depois? 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@marvelous12      você criou variáveis Globais , Assim elas podem ser acessadas em qualquer parte do programa ,   mas  esse for aqui 

 for (; dias_dir <= 35; dias_dir++){

não sei se vai funcionar , não , ainda nunca tinha visto nem imaginado algo assim ,  creio que seja por isso que não vai os outros meses .

Link para o comentário
Compartilhar em outros sites

1 hora atrás, devair1010 disse:

@marvelous12      você criou variáveis Globais , Assim elas podem ser acessadas em qualquer parte do programa ,   mas  esse for aqui 


 for (; dias_dir <= 35; dias_dir++){

não sei se vai funcionar , não , ainda nunca tinha visto nem imaginado algo assim ,  creio que seja por isso que não vai os outros meses .

 

Sim, tem variáveis globais e é uma ideia ruim. É proibido em muitos lugares e é fonte certa de problemas.

 

Num for todos os comandos são opcionais

		for( ;; );

Esse comando é perfeitamente legal. Apenas os '; ' são obrigatórios. O que você não especificar não acontece. Só isso.

Um programa com essa linha apenas vai ficar nisso para sempre, mas está formalmente correto.

Um loop assim

		for ( ; i<0 ; ) funcao();

É um while(i<0) e vai chamar a funcao() enquanto isso valer.

 

Voltando ao tópico


Esse programa vai dar muito trabalho para funcionar assim

  • não devia ter variáveis globais. É uma bobagem. É difícil garantir o que vai ter em dias_dir a cada vez que entra em um loop desses por exemplo. E mesmo que esteja certo é o d1@b0 manter um programa assim funcionando
  • a lógica das colunas está fixa e é um erro. 
  • a lógica de imprimir em colunas está misturada com o fato de ser um calendário e é um outro erro.
  • Esses "números mágicos":
  • image.png.6508d67cd92912a01505782e351915d7.png

    todos vão dar problema. 3,7,5,6,13,20,27 tudo constante... 

    Essa é a unidade de trabalho do programa
    -----------------------------
     XXXXXXXXXXXXXXXXXXXXXXXXXXX                            
    -----------------------------
     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  32  33  34  35 
      36  37  38  39  40  41  42 

    Há claro muitas maneiras de fazer isso. Mas entenda que isso já foi feito assim como está no exemplo para não dar trabalho: todos os meses tem 6 semanas. Basta rodar a sequência pra direita até encaixar o dia da semana e ir preenchendo com "--" o resto dos dias. Por isso falei de ir escrevendo em cima de um "rascunho".

    Uma função minimalista que faz isso podia ser declarada

    char        prepara_mes(char dia_s, char m, int ano, char* fill, FILE* F)

    com dia_s entre 0 e 6 sendo zero para domingo até 6 para sábado, m para o mês para acertar os dias de fevereiro, ano para, digamos, o ano, porque precisa saber se é bissexto, fill é uma string que pode ser "--", e F apontando para um arquivo aberto onde a função vai empilhando os meses um depois do outro. Todos com 10 linhas cada um, mas sem escrever uma constante no programa.

    E a função retorna um char entre 0 e 6. Pra que? Simples: o primeiro dia do mês seguinte. Assim pode usar para um calendário de 3 meses, ou de março a março, ou de 18 meses ou qualquer coisa. Não faz diferença.

    Para o ano inteiro de 2005 por exemplo
     

     	// 2005 comecou em um sábado
    	char dia_s = 6;
    	int ano = 2005;
    	const char* fill = "  ";
        for (int i = 0; i < 18; i += 1)
            dia_s = prepara_mes((char)dia_s, i + 1, ano, fill, F);

    Nesse exemplo deixa em branco os dias ao invés de colocar os "--" que eu acho um pouco feio. No programa cal do Linux é assim. Lá em 3 colunas e com espaços. Eu postei um exemplo.

    E para transpor é uma operação matemática, não depende do calendário ou do conteúdo. E eu postei uma função que faz isso também, para qualquer número de colunas. Mas não vou repetir aqui tudo de novo. O endereço do post está acima.

    Juntando os dois sai o calendário, em 1, 2, 3, 12 ou 20 colunas. 

    Um bonus:

    char        primeiro_dia(int y)
    {
        // metodo de Sakamoto 1992
        int m = 1, d = 1;
        static int t[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
        y -= m < 3;
        return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
    };

    Essa rotina faz o que está escrito aí e determina o dia que faltava pra fechar a conta. 🏆 pro Sakamoto!

     

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@marvelous12 Um Problema encontrei no método

 

Eu acho que precisa para de pensar em uma solução aplicada para casos gerais e foca no que é aparentemente o solicitado: um caso especifico em que a saída é aos pares um abaixo do outro. (Se errei então ignore)

 

 

Identifique o que é mutável e o que é imutável, pois existem de caso especifico e ajuda amortizando o número de operações aritmética exigidas, o que é bem util.

 

Com uso de matrizes amortizamos um pouco a aritmética de ponteiros, no exemplo usei um vetor mesmo, mas pode ser notação de matrizes. Então dado ...

__typeof__(char []) matriz = {
	"|-----------------------------||-----------------------------|\n"
 	"|MES 1                        ||MES 2                        |\n"
 	"|-----------------------------||-----------------------------|\n"
 	"| dom seg ter qua qui sex sab || dom seg ter qua qui sex sab |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
 	"| --  --  --  --  --  --  --  || --  --  --  --  --  --  --  |\n"
	};
printf ("%s", matriz);
       /* ^ Imprimir string 'matriz' na saida padrão */

Identificam  matriz uma variável de tipo (char  [10 * 63 + 1]) ou 631 caractere(s). E como o último caractere é '\000' dizem também que  em C matriz se define de tipo string.

 

Certos que de nada adianta imprimir 'MES 1' é preciso altera essa string. Pra tanto declaro a sub-string: mes_1, porém é preciso antes defini-la, então digamos que a matriz tem 10 linhas e 63 colunas assim tal qual um plano no R2. Disso As coordenadas (2, 2),  que em aritmética de ponteiros equivale à [(2 - 1) * 63 + (2 - 1)], inicia a minha sub-string mes_1 no caractere 'M'.

 

Logo declaramos o apontador: mes_1 assim:

#define X 2
#define Y 2
__typeof__(char *) mes_1 = (matriz + ((Y) - 1) * 0x3F + ((X) - 1));

 

Note: A distância de 'M', pertencente a 'MES 1', e 'M' de 'MES 2' equivale à 31 caracteres.

Disso definimos o apontador: mes_2

#define X 2
#define Y 2
__typeof__(char *) mes_1 = (matriz + ((Y) - 1) * 0x3F + ((X) - 1) + 0x00);
__typeof__(char *) mes_2 = (matriz + ((Y) - 1) * 0x3F + ((X) - 1) + 0x1F);

 

Agora antes de imprimir os dois meses escrevemos seus nomes assim:

(void) (mes_1 [sprintf (mes_1, "%-28s", "Janeiro")] =   ' ');
(void) (mes_2 [sprintf (mes_2, "%-28s", "Fevereiro")] = ' ');

printf ("%s", matriz);
       /* ^ Imprimir string 'matriz' na saida padrão */

Para mais informações: sprintf

 

Outros últimos valores mutáveis são as 42 sub-strings: defina todas, use opcionalmente a mesma lógica matemática que apresentei para os dois nomes (mes_1 e _2) e com isso reduza pela metade o número de operações aritmética na solução em discussão.

 	--  --  --  --  --  --  -- 
 	--  --  --  --  --  --  -- 
 	--  --  --  --  --  --  -- 
 	--  --  --  --  --  --  -- 
 	--  --  --  --  --  --  -- 
 	--  --  --  --  --  --  --

 

Boa Sorte!

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...