Ir ao conteúdo

Posts recomendados

Postado

Bom dia! Eu to com uma dúvida em uma parte de um programa que estou utilizando struct e não consigo descobrir o que é. Se eu passar os parâmetros para a função, aparece o erro "muitos argumentos na chamada da função", e não compila. Se eu não passar, o programa roda, mas a validação sai errada. Tentei criar as variáveis na função mas como é obrigatório utilizar struct, eu descartei essa ideia. Parte do meu código:

#include <stdio.h>


typedef struct{
    int dd, mm, yy;
    bool valido;
}data;

int valida_data();

int main()
{
    data d;
    for(;;){
    printf("Entre com a data (formato DD/MM/YYYY ): ");
    scanf("%d/%d/%d", &d.dd, &d.mm, &d.yy);
    valida_data();
    
    if((d.valido==true)){
        break;
    }

    }
} 


int valida_data(){
    data d;
    //check year
     if (d.yy >= 1900 && d.yy <= 2008)//checar ano
    {

        if (d.mm >= 1 && d.mm <= 12)//checar mes
        {
            //checar dias
            if ((d.dd >= 1 && d.dd <= 31) && (d.mm == 1 || d.mm == 3 || d.mm == 5 || d.mm == 7 || d.mm == 8 || d.mm == 10 || d.mm == 12))
                d.valido = true;
            else if ((d.dd >= 1 && d.dd <= 30) && (d.mm == 4 || d.mm == 6 || d.mm == 9 || d.mm == 11))
                d.valido = true;
            else if ((d.dd >= 1 && d.dd <= 28) && (d.mm == 2))
                d.valido = true;
            else if (d.dd == 20 && d.mm == 2 && (d.yy == 2009))
                d.valido = true;
            else
                printf("Data inválida.\n");
                d.valido = false;
        }
        else
        {
            printf("Mês inválido.\n");
            d.valido = false;
        }
    }
    else
    {
        printf("Ano inválido.\n");
        d.valido = false;
    }
    return d.valido;
}

a saída:image.png.749e0aa202526f63926582f3c286868d.png

se eu adicionar os parâmetros

 for(;;){
    printf("Data de nascimento (formato DD/MM/AAAA): ");
    scanf("%d/%d/%d", &p.dd, &p.mm, &p.yy);
    valida_data_nasc(p.dd, p.mm, p.yy);
    if((p.valido == false)){
        break;
    }
    }

aparece o erro:

image.png.f9c5058ab65a1e593935580787ba845b.png

  • Obrigado 1
Postado

Talvez deva voltar ao livro um pouco e ler sobre isso.

 

Toda a razão de usar struct é ter um nome e um endereço para todo o grupo.

 

bool em C ou qualquer linguagem  pouco ou nada acrescenta a menos que exista um pool de bits e uma coisa dessa alocasse um único bit. Em C não é o caso. No mínimo 8 bits, o tal byte. E zero é falso e qualquer outra coisa é verdadeira. Assim sem bool a vida segue igual.

 

A struct

 

existe uma convenção que trabalha a seu favor de usar uma variável por linha apenas. Assim fica mais fácil de achar e mudar algo dentro da tal struct.

  • bool é pouco para esse caso: são 3 estados: valido, invalido e não testado. Em geral é importante saber se foi testado. Claro que poderia usar um ano negativo ou algo assim, mas são 3 estados. Que tal esquecer o bool e usar -1 0 e 1, o comum em C? Vide strcmp() por exemplo.
  • Outra convenção importante é usar a primeira letra em maiúscula para tipos estruturados assim você sempre sabe que não é uma variável comum e provavelmente precisa de . ou -> para acessar os campos.
  • int é muito grande para esse caso. short basta porque o maior campo é o ano.

Exemplo

 


typedef struct
{
    int dd;
    int mm;
    int yy;
    int valido;

}   Data;

 

Essa linha em branco antes do nome ajuda na listagem a separar os campos.

 

A função

 

Seria mais esperto se a função retornasse +1 para válido e -1 para inválido. Reservado o zero para não-testado.

 

E declare 

 

int valida_data(Data*);

 

Porque? Simples: todo o propósito de usar uma struct é não ter que passar TODA a estrutura. Passe apenas o endereço e retorne valido/invalido.

 

Veja como é mais simples:

 

    Data data = {0};
    data.valido = valida(&data);

 

Acho que sabe que deve mostrar o que leu e o que está testando ou nunca vai saber se a função está mesmo ok. Pode ser um falso positivo, pode ter lido errado.

 

Se antecipe e deixe o programa trabalhar por você e escreva uma função que mostra. C foi escrita pensando nessas coisas: composição através de funções e struct, velocidade, base, deslocamento.

 

Sobre seu código para valida_data()

 

Faça o simples e retorne assim que tiver uma conclusão. Esses if imensos só atrapalham a leitura e manutenção do código.

 

Você começa a testar o ano em uma certa linha. E se o ano for inválido só vai retornar mais de 30 linhas depois.

 

E o código vai caindo para a direita tipo javascript. Só complica. Para você e para quem tenta ler.

 

Compare:

 

        if (d->yy < 1900 || d->yy > 2008) return INVALIDO;

 

Pois é. 

 

Compare o original

 

int valida_data()
{
    data d;
    // check year
    if (d.yy >= 1900 && d.yy <= 2008)  // checar ano
    {
        if (d.mm >= 1 && d.mm <= 12)  // checar mes
        {
            // checar dias
            if ((d.dd >= 1 && d.dd <= 31) &&
                (d.mm == 1 || d.mm == 3 || d.mm == 5 ||
                 d.mm == 7 || d.mm == 8 || d.mm == 10 ||
                 d.mm == 12))
                d.valido = true;
            else if (
                (d.dd >= 1 && d.dd <= 30) &&
                (d.mm == 4 || d.mm == 6 || d.mm == 9 ||
                 d.mm == 11))
                d.valido = true;
            else if (
                (d.dd >= 1 && d.dd <= 28) && (d.mm == 2))
                d.valido = true;
            else if (
                d.dd == 20 && d.mm == 2 && (d.yy == 2009))
                d.valido = true;
            else
                printf("Data inválida.\n");
            d.valido = false;
        }
        else
        {
            printf("Mês inválido.\n");
            d.valido = false;
        }
    }
    else
    {
        printf("Ano inválido.\n");
        d.valido = false;
    }
    return d.valido;
}

 

 

Com isso, que faz praticamente a mesma coisa:

 

int valida_data(Data* d)
{
    d->valido = INVALIDO; // ate prova em contrario
    if (d == NULL) return INVALIDO;
    // especial
    if ( d->dd == 20 && d->mm == 2 && d->yy == 2009) return VALIDO;
    if (d->yy < 1900 || d->yy > 2008) return INVALIDO; // ano
    if (d->mm < 1 || d->mm > 12) return INVALIDO; // mes
    if (d->dd < 1 || d->dd > 31 ) return INVALIDO; // dia

    if ((d->mm == 2) && (d->mm > 28))return INVALIDO; // fev
    // ok entao
    d->valido = VALIDO;
    return VALIDO;
}

 

Nunca, mas nunca mesmo escreva um programa interativo. Use constantes, gere valores. Só vai perder tempo com essas coisas que parecem norma de ler do teclado e usar menus.

 

Quando está testando não pode perder tempo. Compare com essa versão de main()

 

int main(void)
{
    Data data = {0};
    data.valido = valida_data(&data);
    mostra_data(&data);

    Data val = {25, 12, 2007, 0};
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida dia
    val.dd     = 33;
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida mes
    val.dd     = 25;
    val.mm     = -1;
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida ano
    val.mm     = 12;
    val.yy     = 2021;
    val.valido = valida_data(&val);
    mostra_data(&val);
    return 0;
}

 

Que testa algumas das condições e já mostra algo no primeiro instante. E não precisa digitar p. nenhuma.

 

Um EXEMPLO

 

Não é sua solução. Só quero mostrar como pode ser mais direto e legível.

Programas escritos assim em geral rodam certo na primeira vez.

 

saida

 

Data: 00/00/0000. Status: [Invalida]
Data: 25/12/2007. Status: [Valida]
Data: 33/12/2007. Status: [Invalida]
Data: 25/-1/2007. Status: [Invalida]
Data: 25/12/2021. Status: [Invalida]

 

o código

 

#define INVALIDO (-1)
#define VALIDO (1)

#include <stdio.h>

typedef struct
{
    int dd;
    int mm;
    int yy;
    int valido;

}   Data;

int mostra_data(Data*);
int valida_data(Data*);

int main(void)
{
    Data data = {0};
    data.valido = valida_data(&data);
    mostra_data(&data);

    Data val = {25, 12, 2007, 0};
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida dia
    val.dd     = 33;
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida mes
    val.dd     = 25;
    val.mm     = -1;
    val.valido = valida_data(&val);
    mostra_data(&val);
    // invalida ano
    val.mm     = 12;
    val.yy     = 2021;
    val.valido = valida_data(&val);
    mostra_data(&val);
    return 0;
}

int mostra_data(Data* d)
{
    static char* status[] =
    {
        "Invalida",
        "não testada ainda",
        "Valida"
    };
    if (d == NULL) return -1;
    printf(
        "Data: %02d/%02d/%04d. Status: [%s]\n", d->dd,
        d->mm, d->yy, status[1 + d->valido]);
    return 0;
}

int valida_data(Data* d)
{
    d->valido = INVALIDO; // ate prova em contrario
    if (d == NULL) return INVALIDO;
    // especial
    if ( d->dd == 20 && d->mm == 2 && d->yy == 2009) return VALIDO;
    if (d->yy < 1900 || d->yy > 2008) return INVALIDO; // ano
    if (d->mm < 1 || d->mm > 12) return INVALIDO; // mes
    if (d->dd < 1 || d->dd > 31 ) return INVALIDO; // dia

    if ((d->mm == 2) && (d->mm > 28))return INVALIDO; // fev
    // ok entao
    d->valido = VALIDO;
    return VALIDO;
}

 

  • Curtir 2

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...