Ir ao conteúdo
  • Cadastre-se

Posts recomendados

Postado

Fiz um exercício para a faculdade que consiste em criar uma agenda com nome e telefone através de uma lista duplamente encadeada, no meu código para remover um contato era obrigatório ser com o nome, mas ao digitar um número no lugar do nome ele está removendo o primeiro item da lista.

 

 

#include<stdlib.h>
#include <stdio.h>
#include <string.h>
#define TAM_NOME 20
#define TAM_TELEFONE 10

typedef enum {false, true} bool;
typedef struct no{
    char nome[TAM_NOME];
    char telefone[TAM_TELEFONE];
    struct no *prox;
    struct no *ant;
} noContato; //declara tipo

noContato *prim=NULL; //define primeiro elemento como vazio
noContato *ult=NULL; //define ultimo elemento como vazio
int quant=0;

bool insereContatoNaAgenda(noContato *info){ //funcao para inserir dados
    noContato *aux = NULL;
    noContato *atual = prim;
    noContato *novo;
    novo=(noContato*)malloc(sizeof(noContato)); //aloca ponteiro
    while((atual != NULL) && (strcmp(atual->nome,info->nome)<0)){ //percorre lista
        aux = atual;
        atual = atual->prox;
    }
    if(aux == NULL){
        prim = novo;
    }
    else{
        aux->prox = novo;
    }
    if(atual == NULL){
        ult = novo;
    }
    else{
        atual->ant = novo;
    }
    strcpy(novo->nome, info->nome); //adiciona os valores
    strcpy(novo->telefone, info->telefone);
    novo->prox = atual;
    novo->ant = aux;
    quant++;
    return true;
}

void imprimeAgenda(noContato *num){ //impressao da lista
    int i = 0;
    if(prim == NULL && ult == NULL){
        printf("\nLista vazia.\n");
    }else{
        while(num != NULL){
            printf("\nPosicao: %d\nNome: %s\nTelefone: %s\n", i, num->nome, num->telefone);
            num = num->prox;
            i++;
        }
    }
}

bool removeContatoDaAgenda(char remove[TAM_NOME]){ //remover elemento unico
    noContato *aux = NULL;
    noContato *atual = prim;
    while((atual != NULL) && (strcmp(atual->nome,remove)<0)){ //percorre lista
        aux=atual;
        atual=atual->prox;
    }
    if(atual == NULL){
        return false;
    }
    else{
        if(atual == prim){
            prim = atual->prox;
        }
        else{
            aux->prox = atual->prox;
        }
        if(atual == ult){
            ult = aux;
        }
        else{
            atual->prox->ant = aux;
        }
        free(atual); //libera a memoria
        quant--;
        return true;
    }
}

int pesquisaContato(noContato *valor){
    int i = 0;
    noContato *atual = prim;
    while((atual != NULL) && (strcmp(atual->nome,valor->nome)!=0) && (strcmp(atual->telefone,valor->telefone)!=0)){//percorre lista procurando valor igual
        atual = atual->prox;
        i++;
    }
    if(atual == NULL){
        return -1;
    }
    else{
        return i;
    }
}

void destroiAgenda(){ //apaga toda a lista
    noContato *atual = prim;
    noContato *apaga;
    while(atual != NULL){
        apaga = atual;
        atual = atual->prox;
        free(apaga);
    }
}

int main(int argc, char *argv[]){
    int opc, cont = 0;
    char nomeR[TAM_NOME];
    noContato *dados = (noContato*)malloc(sizeof(noContato));
    do{ //do..while para o menu
        printf(">> 1 para inserir um contato na agenda\n>> 2 para remover um contato na agenda\n>> 3 para listar todos os contatos da agenda\n>> 4 para sair da agenda\nDigite a opcao desejada:\n");
        scanf("%d", &opc);
        getchar();
        switch(opc){
            case 1:
                printf("Digite o nome:");
                gets(dados->nome);
                printf("Digite o telefone:");
                gets(dados->telefone);
                if(pesquisaContato(dados)==-1){
                    if(insereContatoNaAgenda(dados)==true){
                        printf("Nome inserido com sucesso.\n");
                    }
                    else{
                        printf("Nao foi possivel inserir o nome.\n");
                    }
                }
                else{
                    printf("Dados ja existentes.\n");
                }
                printf("\n");
                break;
            case 2:
                printf("Digite o nome a ser removido:");
                gets(nomeR);
                if(removeContatoDaAgenda(nomeR)==true){
                    printf("Nome removido com sucesso.\n");
                }
                else{
                    printf("Nao foi possivel remover.\n");    
                }
                printf("\n");
                break;
            case 3:
                imprimeAgenda(prim);
                printf("\n");
                break;
            case 4:
                cont++;
                destroiAgenda();
                break;
            default:
                printf("Opcao invalida\n");
                printf("\n");
                break;
        }
    }while(cont==0);
}//end main

 

image.thumb.png.b3a702f29318c73e42371abef67c020b.png

Postado

@Erkling  Olá,

 

Utilize a flag -Wall para o compilador, alterei o gets() para o fgets() e funcionou. Deixarei um código como exemplo:

 

int main(int argc, char *argv[]){
    int opc, cont = 0;
    char nomeR[TAM_NOME];
    noContato *dados = (noContato*)malloc(sizeof(noContato));
    do{ //do..while para o menu
        printf(">> 1 para inserir um contato na agenda\n>> 2 para remover um contato na agenda\n>> 3 para listar todos os contatos da agenda\n>> 4 para sair da agenda\nDigite a opcao desejada:\n");
        scanf("%d", &opc);
        getchar();
        switch(opc){
            case 1:
                printf("Digite o nome:");
                fgets(dados->nome, TAM_NOME, stdin);
                printf("Digite o telefone:");
                fgets(dados->telefone, TAM_TELEFONE, stdin);
                if(pesquisaContato(dados)==-1){
                    if(insereContatoNaAgenda(dados)==true){
                        printf("Nome inserido com sucesso.\n");
                    }
                    else{
                        printf("Nao foi possivel inserir o nome.\n");
                    }
                }
                else{
                    printf("Dados ja existentes.\n");
                }
                printf("\n");
                break;
            case 2:
                printf("Digite o nome a ser removido:");
                fgets(nomeR, TAM_NOME, stdin);
                if(removeContatoDaAgenda(nomeR)==true){
                    printf("Nome removido com sucesso.\n");
                }
                else{
                    printf("Nao foi possivel remover.\n");    
                }
                printf("\n");
                break;
            case 3:
                imprimeAgenda(prim);
                printf("\n");
                break;
            case 4:
                cont++;
                destroiAgenda();
                break;
            default:
                printf("Opcao invalida\n");
                printf("\n");
                break;
        }
    }while(cont==0);
}//end main

 

Espero ter lhe ajudado em algo, até mais!

  • Curtir 1
Postado

Acho que sabe agora que gets() foi condenada há décadas. Use fgets(), mas entenda que gets() e fgets() retornam ao ler um '\n' na entrada e ele vem na linha então deve tratar isso de acordo. Em geral é ok porque vai sair com fputs() que faz a mesma coisa. Mas se vai usar no programa pode precisar tirar o valor de lá. Como ele está sempre lá no fim é trivial. 

 

  • Não use variáveis globais. Nunca. Em geral nas empresas é proibido, nas escolas custa nota. E não é esperto. Sempre dá problema.
  • main() deve ser a primeira função de seu programa, sempre. Se possível em um arquivo separado. Isso ajuda você e outros que venham a ler seu programa.
  • não escreva duas vezes código para fazer a mesma coisa: para remover um contato você primeiro pesquisa, igualzinho naquela função pesquisa()... Então chame aquela função. Assim se errar ou precisar mudar aquilo vai mudar em um lugar só.
  • pesquisa() devolver o número do cara é pouco útil. Que vai fazer com esse número? No momento seguinte pode ter inserido alguém na frente e o número mudou... Retorne o endereço dele
  • Entenda que uma lista é uma coleção de nós. Ela não é um nó. Você pode fazer de conta que é, como em geral parece que os caras ensinam e os alunos tentam. Mas não é.

     Do seu programa:
     
    noContato* prim = NULL; //define primeiro elemento como vazio
    noContato* ult = NULL; //define ultimo elemento como vazio
    int quant = 0;
  • Isso só arruma problemas para você mesmo: imagine se precisar usar duas listas, do nada. E acaba tendo que passar parâmetros pra todo lado toda hora. Ou pior, como fez, usando valores globais. E com nomes assim simples: prim e ult. Outro dia tinha eu vi um programa com uma variável global chamada aux. E o que aconteceu? No meio do programa o autor declarava outra e lá se ia a estrutura toda.

Imagine algo assim


struct no
{
    void*      item;
    struct no* next;
    struct no* prev;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

 

E você pode declarar
 

Lista	livros;
Lista*	playList;
Lista	novas[8];

 

E junto com a lista vão os ponteiros, o tamanho e o limite, por exemplo. Para cada lista

  • Curtir 1

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