Ir ao conteúdo
  • Cadastre-se

C Exercício de Listas Encadeadas


Posts recomendados

Bom, estou fazendo um exercício de listas encadeadas para um trabalho de faculdade mas estou com dois problemas que eu não consigo resolver, se alguém puder me explicar o que tenho que fazer ficaria muito agradecido. Vamos lá, o exercício é um programa de cadastro de tarefas da faculdade, segue a descrição:

 

O programa deverá conter o tipo estruturado Tarefa composto pelos campos

id (int)

titulo (string)

descricao (string)

categoria (string)

data_entrega (do tipo Data)

concluido (int)

proximo (do tipo struct tarefa)

E o tipo estruturado Data com os campos dia, mes e ano do tipo int.

 

O programa deverá incluir as opções para:

Encerrar

inserir uma nova tarefa

excluir uma tarefa

listar todas as tarefas

mostrar todas as tarefas dada uma categoria

mostrar a tarefa não concluída com a menor data de entrega

mostrar todas as tarefas concluídas (concluído igual a um)

mostrar todas as tarefas não concluídas (concluído igual a zero)

marcar uma tarefa como concluída dado o id

 

 

eu consegui fazer quase todos, mas "marcar uma tarefa como concluída dado o id" e "mostrar a tarefa nao concluida com a menor data de entrega" não saem de jeito nenhum.

 

segue o código abaixo:

 

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

enum opcao
{
    ENCERRAR,
    INSERIR,
    EXCLUIR,
    LISTAR,
    MOSTRAR_CATEGORIA,
    MOSTRAR_MENOR_DATA,
    MOSTRAR_CONCLUIDAS,
    MOSTRAR_N_CONCLUIDAS,
    MARCAR_ID
};
typedef enum opcao Opcao;

struct data
{
    int ano;
    int mes;
    int dia;
};
typedef struct data Data;

struct tarefa
{
    int id;
    char titulo[50];
    char descricao[15]; // 999.999.999-99
    char categoria[20]; // +99 (99) 99999-9999
    Data data;
    int concluida;
    struct tarefa * proximo;
};
typedef struct tarefa Tarefa;

Opcao menu()
{
    Opcao op;
    printf("Selecione uma opção:\n");
    printf("\t%d. Encerrar\n", ENCERRAR);
    printf("\t%d. Inserir\n", INSERIR);
    printf("\t%d. Excluir\n", EXCLUIR);
    printf("\t%d. Listar\n", LISTAR);
    printf("\t%d. Tarefas nao concluidas com menor data de entrega:\n", MOSTRAR_MENOR_DATA);
    printf("\t%d. Tarefas concluidas\n", MOSTRAR_CONCLUIDAS);
    printf("\t%d. Tarefas nao concluidas\n", MOSTRAR_N_CONCLUIDAS);
    printf("\t%d. Marcar como concluida por Id\n", MARCAR_ID);
    printf("> ");
    scanf("%d", &op);
    return op;
}

Tarefa* nova_tarefa()
{
    static int id = 0;
    Tarefa* tarefa = malloc (sizeof *tarefa);
    id++;
    tarefa->id = id;
    printf("Titulo: ");
    scanf(" %99[^\n]", tarefa->titulo);
    printf("Descricao: ");
    scanf(" %99[^\n]", tarefa->descricao);
    printf("Categoria: ");
    scanf(" %99[^\n]", tarefa->categoria);
    printf("Data:\n");
    printf("\t Dia: ");
    scanf(" %d", &tarefa->data.dia);
    printf("\t Mes: ");
    scanf(" %d", &tarefa->data.mes);
    printf("\t Ano: ");
    scanf(" %d", &tarefa->data.ano);
    printf("\t Concluida: ");
    scanf(" %d", &tarefa->concluida);
    return tarefa;
}

Tarefa* inserir(Tarefa* lista)
{
    Tarefa* nova = nova_tarefa();
    nova->proximo = lista;
    return nova;
}

void mostra_tarefa(Tarefa* tarefa)
{
    printf("%d: %s\n", tarefa->id, tarefa->titulo);
    printf("Descricao: %s\n", tarefa->descricao);
    printf("Categoria: %s\n", tarefa->categoria);
    Data data = tarefa->data;
    printf("Data: %d/%d/%d.\n",
           data.dia, data.mes, data.ano);
}

void listar(Tarefa* lista)
{
    Tarefa* i;
    for(i=lista; i != NULL; i = i->proximo)
    {
        mostra_tarefa(i);
        printf("\n");
    }
}


void consultar_categoria(Tarefa* lista)
{
    char categoria[100];
    printf("Categoria: ");
    scanf(" %99[^\n]", categoria);
    Tarefa* i;
    for(i=lista; i != NULL; i = i->proximo)
    {
        if (strcmp(i->categoria, categoria) == 0)
        {
            mostra_tarefa(i);
        }
    }
}

Tarefa* excluir (Tarefa* lista)
{
    int id;
    printf("Id: ");
    scanf("%d", &id);
    Tarefa* ant = NULL; // ponteiro para o anterior
    Tarefa* i; // ponteiro que percorre a lista
    /* procura elemento v na lista */
    for (i = lista; i != NULL && i->id != id; i = i->proximo)
    {
        ant = i;
    }
    /* verifica se achou o elemento */
    if (i == NULL)
    {
        return lista; // não achou
    }
    /* retira elemento */
    if (ant == NULL)
    {
        lista = i->proximo; // remove o primeiro
    }
    else
    {
        ant->proximo = i->proximo; // remove do meio
    }
    free(i); // libera memória do elemento removido
    return lista; // retorna o ponteiro para o início
}

Tarefa* liberar(Tarefa *tarefas){
  Tarefa *i;
  Tarefa *aux;
  for (i = tarefas; i != NULL; i = aux) {
    aux = i->proximo;
    free(i);
  }
  return NULL;
}

void mostrar_concluidas (Tarefa* lista){
    Tarefa* i;
    for(i=lista; i != NULL; i = i->proximo)
    {
        if (i->concluida == 1)
        {
            mostra_tarefa(i);
        }
    }
}

void mostrar_n_concluidas (Tarefa* lista){
    Tarefa* i;
    for(i=lista; i != NULL; i = i->proximo)
    {
        if (i->concluida == 0)
        {
            mostra_tarefa(i);
        }
    }
}

void marcar_concluida_id (Tarefa* lista){
    Tarefa* i;
    int id;
    printf("Id: ");
    scanf("%d", &id);
    for(i=lista; i != NULL && i->id != id; i = i->proximo)
    {
        if(i != NULL){
            i->concluida=1;
        }
    }
}

void tarefa_menor_data (Tarefa* lista){
    Tarefa* a;
    Tarefa* i;
    for (i=(lista-1); i != NULL ; i->proximo)
    if(i->concluida==0){
            if(i->data.ano < (i-1)->data.ano){
                a=i;
            } else if (i->data.ano == (i-1)->data.ano){
                if(i->data.mes < (i-1)->data.mes){
                    a=i;
                } else if (i->data.mes == (i-1)->data.mes){
                    if(i->data.dia < (i-1)->data.dia){
                        a=i;
                    }
                }
            }
        }
                        else
                            printf("Nao ha tarefas abertas\n");

    mostra_tarefa(a);
}


int main(void)
{
    setlocale(LC_ALL, "");
    Tarefa *tarefas = NULL; // vetor de tarefas

    /**
    Exemplo:
                 i
      -----------↓-------
      |8|3|5|6|2| | | | |
      -------------------
       0 1 2 3 4 5 6 7 8
      capacidade: 9
      tamanho: 5
    */

    Opcao opcao = ENCERRAR;
    do
    {
        opcao = menu();
        switch (opcao)
        {
        case ENCERRAR:
            tarefas = liberar(tarefas);
            printf("Encerrando...\n");
            break;
        case INSERIR:
            tarefas = inserir(tarefas);
            break;
        case EXCLUIR:
            tarefas = excluir(tarefas);
            break;
        case LISTAR:
            listar(tarefas);
            break;
        case MOSTRAR_CATEGORIA:
            consultar_categoria(tarefas);
            break;
        case MOSTRAR_CONCLUIDAS:
            mostrar_concluidas(tarefas);
            break;
        case MOSTRAR_N_CONCLUIDAS:
            mostrar_n_concluidas(tarefas);
            break;
        case MARCAR_ID:
            marcar_concluida_id(tarefas);
            break;
        case MOSTRAR_MENOR_DATA:
            tarefa_menor_data(tarefas);
            break;

        default:
            printf("Opcão inválida [%d]\n", opcao);
        }
    }
    while (opcao != ENCERRAR);

    return 0;
}

 

 

HALP PLS

Link para o comentário
Compartilhar em outros sites

Veja se assim funciona:

void marcar_concluida_id (Tarefa* lista){
    Tarefa* i;
    int id;
    printf("Id: ");
    scanf("%d", &id);
    for(i=lista; i != NULL; i = i->proximo)
    {
      if (i->id == id) i->concluida=1;        
    }
}

Do jeito que estava antes, você estava fazendo o contrário (concluindo todos que o id NÃO fosse igual).

Listas encandeadas só vão para frente.

Isso de  subtrair 1 do ponteiro NÃO funciona do jeito que você acha que funciona (não vai pegar o anterior, você só está corrompendo o ponteiro, fazendo-o apontar para endereço de memória não alocado por ele:

           if(i->data.ano < (i-1)->data.ano) //NAO FACA ISSO!

Veja se assim funciona:

 void tarefa_menor_data (Tarefa* lista){
    Tarefa* a = lista;
    Tarefa* i;
    for (i=lista; i != NULL ; i->proximo)
    if(i->concluida==0){
            if(i->data.ano < a->data.ano){
                a=i;
            } else if (i->data.ano == a->data.ano){
                if(i->data.mes < a->data.mes){
                    a=i;
                } else if (i->data.mes == a->data.mes){
                    if(i->data.dia < a->data.dia){
                        a=i;
                    }
                }
            }
        }
     if ((a != NULL) && (a->concluido == 0)) mostra_tarefa(a);
     else printf("Nao ha tarefas abertas\n");
}

 

Link para o comentário
Compartilhar em outros sites

Obrigado pela ajuda, realmente nao tinha ideia de que estava corrompendo o ponteiro, funcionou o codigo para marcar a tarefa como concluída a partir do ID, porém o de mostrar a tarefa nao concluida com a menor data de entrega, nao vai ainda, quando eu entro nessa opção o programa simplesmente trava.

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!