Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

brhue

Agenda de Contatos em C.

Recommended Posts

Para quem quiser um pequeno exemplo, de uma Agenda (básica) em C, com Nome e Telefone, mais algumas funcoes básicas.

O programa esta com fácil entendimento, para quem quiser melhorar ou modificar.

 

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

/*Estrutura agenda */
typedef struct agenda
{
    char nome[20];
    int telefone;
}agenda;

/*Varivaies globais*/
FILE *arq;
agenda contato;

/*Funcao menu, onde retorna alguma opcao*/
char menu()
{
    system("cls");
    printf("***************  Agenda de Contatos: ***************\n");
    printf("\n");
    printf("[1] - Adicionar contato\n");
    printf("[2] - Mostrar lisa de contatos\n");
    printf("[3] - Procurar contato pelo Nome\n");
    printf("[4] - Procurar contato pelo Numero\n");
    printf("[5] - Modificar contato\n");
    printf("[6] - Remover contato\n");
    printf("[9] - Sair\n");
    printf("\n");
    printf("> ");
    return (toupper(getche()));
}

/*Funcao que serve para verificar se no arquivo "banco.bin", já existe nome do contato, retornando 1*/
int verifica(char nome[])
{
    fread(&contato,sizeof(agenda),1,arq);
    while(!feof(arq))
    {
        if (strcmp(contato.nome,nome) == 0)

        {
            fseek(arq,-sizeof(agenda),SEEK_CUR);
            return 1;
        }
        fread(&contato,sizeof(agenda),1,arq);
    }

    return 0;
}

/*Funcao que serve para verificar se no arquivo "banco.bin", já existe telefone do contato, retornando 1*/
int verifica_num(int num)
{
    fread(&contato,sizeof(agenda),1,arq);
    while(!feof(arq))
    {
        if (contato.telefone == num)
        {
            fseek(arq,-sizeof(agenda),SEEK_CUR);
            return 1;
        }
        fread(&contato,sizeof(agenda),1,arq);
    }
    return 0;
}

/*Funcao para add contatos na agenda*/
void adicionar_contato()
{
    char nome[20];

    arq = fopen("banco.bin","a+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    printf("\n\n");
    printf("Digite o nome: ");
    fflush(stdin);
    gets(nome);

    if (verifica(nome) == 1)
    {

        printf("\nNome ja existe.\n");
    }
    else
    {
        strcpy(contato.nome,nome);
        printf("Digite o telefone: ");
        scanf("%d", &contato.telefone);
        fwrite(&contato,sizeof(agenda),1,arq);
    }
    fclose(arq);
}

/*Funcao para modificar contato*/
void modificar()
{
    char nome[20];

    arq = fopen("banco.bin","r+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    printf("\n\n");
    printf("Digite nome do contato: ");
    fflush(stdin);
    gets(nome);

    if (verifica(nome) == 1)
    {
        printf("\nDigite um novo nome: ");
        fflush(stdin);
        gets(nome);
        strcpy(contato.nome,nome);
        printf("\nDigite um novo numero de telefone: ");
        scanf("%d", &contato.telefone);
        fwrite(&contato,sizeof(agenda),1,arq);
    }

    else
    {
        printf("\nNome nao existe.\n");
    }

    fclose(arq);
}

/*Funcao para remover contato*/
void remover_contato()
{
    char nome[20];
    FILE *tmp;

    arq = fopen("banco.bin","r+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    tmp = fopen("banco.txt","a+b");

    printf("\n\n");
    printf("Digite nome do contato: ");
    fflush(stdin);
    gets(nome);

    fread(&contato,sizeof(agenda),1,arq);
    while (!feof(arq))
    {

        if (strcmp(contato.nome,nome) != 0) //compara o nome, para exceder
        {
           fwrite(&contato,sizeof(agenda),1,tmp); //grava no arquivo temp
        }
        fread(&contato,sizeof(agenda),1,arq); //lê arquivo

    }
    fclose(arq);
    fclose(tmp);

    system("del banco.bin");
    system("ren banco.txt banco.bin");
}

/*Procura contato pelo nome*/
void procura_nome()
{
    char nome[20];

    arq = fopen("banco.bin","r+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    printf("\n\n");
    printf("Digite o nome: ");
    fflush(stdin);
    gets(nome);

    if (verifica(nome) == 1)
    {
        fread(&contato,sizeof(agenda),1,arq);
        printf("\n\n");
        printf("----------------------------------------\n");
        printf("CONTATOS          |            TELEFONE \n");
        printf("----------------------------------------\n");
        printf("%-20s           %8d\n", contato.nome,contato.telefone);
        printf("----------------------------------------\n");

    }

    else
    {
        printf("\nContato nao existe.\n");
    }

    fclose(arq);
}

/*Procura contato pelo telefone*/
void procura_num()
{
    int num;

    arq = fopen("banco.bin","r+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    printf("\n\n");
    printf("Digite o telefone: ");
    scanf("%d", &num);

    if (verifica_num(num) == 1)
    {
        fread(&contato,sizeof(agenda),1,arq);
        printf("\n\n");
        printf("----------------------------------------\n");
        printf("CONTATOS          |            TELEFONE \n");
        printf("----------------------------------------\n");
        printf("%-20s           %8d\n", contato.nome,contato.telefone);
        printf("----------------------------------------\n");
    }

    else
    {
        printf("\nContato nao existe.\n");
    }

    fclose(arq);
}

/*Lista contatos*/
void mostrar_lista()
{
    arq = fopen("banco.bin","r+b");
    if (arq == NULL)
    {
        printf("Erro ao abrir arquivo\n");
        return;
    }

    printf("\n\n");
    printf("----------------------------------------\n");
    printf("CONTATOS          |            TELEFONE \n");
    printf("----------------------------------------\n");

    fread(&contato,sizeof(agenda),1,arq);
    while (!feof(arq))
    {
        printf("%-20s           %8d\n", contato.nome,contato.telefone);
        fread(&contato,sizeof(agenda),1,arq);
    }
    printf("----------------------------------------\n");

    fclose(arq);
}

/*Funcao principal*/
int main()
{
    char op;

    do
    {
        op = menu();

        switch(op)
        {
            case '1': adicionar_contato(); break;
            case '2': mostrar_lista(); break;
            case '3': procura_nome(); break;
            case '4': procura_num(); break;
            case '5': modificar(); break;
            case '6': remover_contato(); break;
        }

        printf("\n");
        system("PAUSE");

    }while (op != '9');

    return 0;
}

 

brHUE

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre essa função:

int verifica(char nome[])
{
    fread(&contato,sizeof(agenda),1,arq);
    while(!feof(arq))
    {
        if (strcmp(contato.nome,nome) == 0)

        {
            fseek(arq,-sizeof(agenda),SEEK_CUR);
            return 1;
        }
        fread(&contato,sizeof(agenda),1,arq);
    }

    return 0;
}

É possível diminuir a quantidade de chamadas à função 'fread()':

int verifica (char nome[])
{
	while (fread(&contato, sizeof(agenda), 1, arq))
		if (!strcmp(contato.nome, nome))
			return 1;
	return 0;
}

 

Warning:

 

General: TDM-GCC 4.8.1 64-bit Release
Executing gcc.exe...

 

In function 'verifica_num':
C:\Users\*****\Desktop\teste.c:53:13: warning: overflow in implicit constant conversion [-Woverflow]
fseek(arq,-sizeof(agenda),SEEK_CUR);
^

Compartilhar este post


Link para o post
Compartilhar em outros sites

@

 

Em verifica(char nome[]), preciso da funcao fseek para posicionar o ponteiro, ao acesso certo de registro, para que os registro sejam acessados sequencialmente.

 

Exemplo:

 

Ao procurar por um numero 5.

 

Cada acesso de leitura/gravacao desloca o ponteiro para frente de um valor correspondente quantidade de bytes lidos/gravados.

 

\/

| 1 | 4 | 5 | 7 |

 

\/

| 1 | 4 | 5 | 7 |

 

\/

| 1 | 4 | 5 | 7 |

 

\/

| 1 | 4 | 5 | 7 | (Aqui o numero 5 foi encontrado, mas o ponteiro esta posicionado para o inicio do proximo registro. Por isso precisa usar a funcao fseek, onde -sizeof(agenda), significando um deslocamento para tras.)

 

\/

| 1 | 4 | 5 | 7 |

...

 

Em...

int verifica (char nome[])
{
	while (fread(&contato, sizeof(agenda), 1, arq))
		if (!strcmp(contato.nome, nome))
			return 1;
	return 0;
}

Preciso do feof, quando o ponteiro estiver posicionado depois do ultimo registro retorna 1, indicando fim do arquivo.

 

Sobre a Warning, no codeblocks nao mencionou nenhum erro/warning. Não sei sobre isso..

 

General: TDM-GCC 4.8.1 64-bit Release
Executing gcc.exe...

 

In function 'verifica_num':
C:\Users\*****\Desktop\teste.c:53:13: warning: overflow in implicit constant conversion [-Woverflow]
fseek(arq,-sizeof(agenda),SEEK_CUR);
^

 

....

Talvez o que eu disse não seria o melhor jeito, até mesmo porque ainda estudo C.

....

 

brHUE

Compartilhar este post


Link para o post
Compartilhar em outros sites

A funcionalidade é: informar se existe o código ou nome no registro.

Não é necessário voltar o ponteiro para o registro anterior, a menos que você tenha que retornar o registro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Gets -> risco de segurança (buffer overflow). Use fgets.

Fflush(stdin) -> segundo o padrão ISO, tem comportamento indefinido. Use outra coisa p/ limpar a entrada. Tem um tópico fixo sobre isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@

 

Sobre retornar o registro.. seria preciso naquele código, pelo fato que em ...

 

...

 

if (verifica(nome) == 1)
fread(&contato,sizeof(agenda),1,arq);
...
tem o fread dentro do if (verifica(nome) == 1)... Tirando esse fread nas funcoes, realmente nao precisa do fseek.
------------------------------------------------------------------------------------------------------------------------------------------------
Depois de postar o código, eu li sobre Gets e Fflush ...
Realmente, nao é recomendado....
brHUE

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.