Agenda eletronica com banco de dados em arquivo texto

Publicado por Allan Barcelos (última atualização em 14/08/2011)

[ Hits: 15.816 ]

Homepage: https://barcelos.dev

Download agenda_.cpp




Agenda escrita em C# usando Devc++ como editor.
É uma agenda simples com uso de "strucs" e banco de
dados em arquivo texto externo, esta todo comentado
bem fácil de compreender.

  



Esconder código-fonte

/*
    Trabalho Programação
    Universidade Federal do Triangulo Mineiro - UFTM
    Allan Ricardo Azevedo Barcelos  
    Jordana Carvalho Arruda         
    Compilador: DevC++
    Plugin adicional para DevC++: conio-2.0-1mol (em anexo)

    O arquivo esta todo comentado.
    Usamos como base de referência os seguintes sites:
           http://www.cplusplus.com/reference/

           http://www.hardware.com.br/comunidade/cor-textcolor/1106341/
            *Neste link esclarecemos duvidas quanto a mudar a cor de texto,
            nele descobrimos a conio2.h biblioteca conio.h com mais recursos,

            no codeblocks costuma dar problemas por faltar aquela biblioteca



*/

#include <stdio.h>
#include <string.h> // Biblioteca para manipulação de strings
#include <stdlib.h>
#include <conio.h>

// Caso esteja usando DevC++ com o plugin conio2.h instalado descomente a linha abaixo
//Descomente tambem as linhas 82 e 125 assim ficará colorido algumas partes.

//#include <conio2.h>
#include <ctype.h> //Biblioteca para manipulação de caracteres.

/*
    typedef struct: declara variavel no caso vetor como tipo de estrutura
    no caso abaixo declaro a tabela agenda como estrutura contendo nome e tel
*/
typedef struct Agenda
{
        char nome[20];
        char tel[15];
}tab_agenda;

// Protótipos
void Inclusao(void); // prototipo da função de inclusão, void  nao recebe nada.
void Listar(void); // prototipo da função de listar. idem acima
void Ordenar(void); // prototipo da função de ordenar. idem acima
void Pesquisar(void); // prototipo da função de pesquisa. idem acima
void Menu(void); // prototipo da função de menu. idem acima
char ValidaResp(); // prototipo da função de validaresp recebe o valor op

static int qntd = 0;
/*
Declaração da estrutura tab_agenda como vetor tab[50]
*/
tab_agenda Tab[50];
/*
prototipo da função FILE

Serve para abrir um arquivo para usar a função fopen a qual retorna um ponteiro para FILE.
Você pode usar o ponteiro do arquivo para permitir que o compilador execute
funções de entrada e saída no arquivo.
*/
FILE *fp;


/*

função Principal

*/
int main (){
    //Inicia a variável que receberá a tecla pressionada
    int var;

    printf("\n\n\n\n\n");
    printf(" ******************************************* \n\n");
    printf("               AGENDA ELETRONICA             \n\n");
    printf(" ******************************************* \n\n");

    printf(" ******************************************* \n\n");
    printf(" Allan Ricardo Azevedo Barcelos  - 201110945 \n\n");
    printf(" Jordana Carvalho Arruda         - 201010847 \n\n");
    printf(" ******************************************* \n\n");
  //  textcolor(RED);
    printf("         Presione enter para iniciar         \n");


    var=getch();
    /*
    Ao invez de teclar ENTER a pessoa teclar ESC o programa fecha
    colocamos por questão de estetica
    27 é o valor da tecla ESC
    Fonte: http://www.asciitable.com/ alem desta fonte  fizemos um
    teste com um programa(Codigo abaixo).



    Programa usado para teste e descobrir numero de teclas



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


        //Tabela ASCII usada: http://www.asciitable.com/
        int main(){
        char tcl;

        int num;

        tcl = getch();

        printf("Tecla precionada: %c .Pressione ela de novo \n", tcl);

        num = getch();

        printf("N%cmero na Tabela ASCII da tecla %c: %i",163,130, num);

        system("PAUSE");

        }


    */
  //  textcolor(LIGHTGRAY);
    if(var == 27){ exit(1);}
    Menu();
    system("pause");
}



/*##############################################################*/
//                                                                                                                                            //
//                                                                                                                                            //
//                      INICIO DAS FUNÇÕES                                                                                     //
//                                                                                                                                            //
//                                                                                                                                            //
/*##############################################################*/




//Função para incluir dados no arquivo agenda.txt

void Inclusao(void){
     int add = 0, escrita;
     //decalro variavel como 's'(sim) senão a funçaõ nao funciona na primeira vez executada
     char op = 's';

    //fopen abre o arquivo agenda.txt e coloca o ponteiro no final para gravação

    /*
    ###PARAMETROS###
    "r" Abre um arquivo para leitura. O arquivo deve existir.

    "w" Criar um arquivo vazio para escrita. Se um arquivo com o mesmo nome já existir seu
            conteúdo é apagado e o arquivo é tratado como um novo arquivo vazio.

    "a" Anexar em um arquivo. Operações de escrita anexar dados ao final do arquivo. O arquivo
            é criado se ele não existe.

    "r+" Abre um arquivo para atualizar ambos leitura e escrita. O arquivo deve existir.

    "w+" Criar um arquivo vazio para ambos leitura e escrita. Se um arquivo com o mesmo
            nome já existir seu conteúdo é apagado e o arquivo é tratado como um novo arquivo vazio.

    "a+" Abre um arquivo para leitura e acrescentar. Todas as operações de escrita são realizadas no
            final do arquivo, protegendo o conteúdo anterior para ser substituído.

        Você pode reposicionar (fseek, rewind) o ponteiro interno para qualquer parte do arquivo para
        leitura, mas as operações de escrita vai movê-lo de volta para o final do arquivo. O arquivo é
        criado se ele não existe.

    Referência: http://www.cplusplus.com/reference/clibrary/cstdio/fopen/

    */

    //se a abertura for igual a NULL houve erro
    //Podem ocorrer erros de leitira e escrita no S.O
     if ((fp = fopen("agenda.txt", "a")) == NULL)
     {
        printf ("Erro! Arquivo não pode ser aberto!\n");
        printf ("Faltam dados!\n");
        getch();
        //fecha programa
        exit(1);
     }
     //Enquanto o add menor 35 e operador for 's'(sim) repete este bloco.
     //caso for maior que 35 pula para campo do telefone
     //Pensei em usar fgets aos invez de gets mas tive problemas com a formatação sei lah.

     while ((add < 35) && (op == 's'))
     {

           //A função gets() lê uma string.
           /*
           Haviam dicas em foruns para não usar 'gets'  porque ela é uma função que simplesmente lê dados de um buffer
           e isso pode ser perigoso pois dependendo da situação não prevista que acontecer, pode ser explorada uma situação
           de buffer overflow.

           Usei porque achei mais simples e acredito por este ser um programa simples não teremos problemas
           */

           printf ("Digite o nome....: ");
           gets(Tab[add].nome);
           printf ("Digite o Telefone: ");
           gets(Tab[add].tel);

           escrita = fwrite(&Tab[add], sizeof(struct Agenda) ,1,fp);
            /*
            Como funciona: é gravado em tab[] os dados = tab[].nome tab[].tel com todos seus caracteres
            Exemplo: "Fulano          33333333   " os espaços em branco são "lacunas" não preenchidas
            e isto é gravado no arquivo texto

            */

           if (escrita == 1) {
               printf(" \n Salvo com sucesso! ");
           }
           add++;
           op = ValidaResp();
           qntd++;
     }
     fclose (fp);
}



// Ordena alfabeticamente
void Ordenar(void){

/*

Esta função é responsavel por Ordenar os nomes na agenda
ela abre o arquivo agenda.txt e o reescreve ordenando
os nomes em ordem alfabetica.

Funcionamento: A função le o arquivo e apaga o antigo para gerar um
novo com dados ordenados. Ele pega todos os dados e compara entre eles
e coloca em priemiro lugar o "maior" e grava no arquivo e assim faz
sucessivas vezes gravando no arquivo a cada comparação.

*/
   //vetor tab_agenda
    tab_agenda vet;
    int numconts,i,j,k,escrita;
    char *string_a, *string_b;


        numconts = qntd; // numconts recebe a quantidade de contatos inscritos
        //enquanto i for menos que numconts executa isso
        for ( i = 0 ; i < numconts ; i++ ){
            //damos o valor de nome a string_a
               string_a = Tab[i].nome;
                //enquanto j for menos que numconts executa isso, claoq ue j inicia com o acrescimento de i
               for ( j = i+1 ; j < numconts ; j++ ){
                   //damos o valor do nome subsequente a string_b
                   string_b = Tab[j].nome;
                   //faz a comparação com strcmp
                   if ( strcmp ( string_a, string_b ) > 0 ){
                        vet = Tab[i];
                        Tab[i] = Tab[j];
                        Tab[j] = vet;
                   }
               }
        }
    //Remove o arquivo agenda.txt
    remove("agenda.txt");
    if ((fp = fopen("agenda.txt", "w+")) == NULL){
        // Pode ocorrer erro caso não haja permissão de leitura e/ou escrita (comum em linux)
        printf ("Erro!\n");
        getch();
        exit(1);
    }
     // Inicia a reescrita com os nomes ordenados
    for ( k = 0 ; k < numconts ; k++ ){
         //fwrite abre o arquivo para escrita
           escrita = fwrite (&Tab[k], sizeof(struct Agenda) ,1,fp);
           //apos a escrita retorna valor 1 se diferente houve erro
           if (escrita != 1) {

               // Pode ocorrer erro caso não haja permissão de leitura e/ou escrita (comum em linux)
               printf(" \n Erro ! ");
           }
    }
     //fclose: fecha o arquivo e salva
     fclose(fp);
     printf("\n Lista Ordenada! \n");
     getch();
}

// Pesquisar contato pelo nome

void Pesquisar(void){
     int indice = 0, leitura = 1, cont = 0;
     char nome[20];

     if ((fp = fopen("agenda.txt", "r")) == NULL){
     // Pode ocorrer erro caso não haja permissão de leitura e/ou escrita (comum em linux)
     printf (" O arquivo da lista não pode ser aberto!\n");
     printf (" Insira dados!\n");
     getch();
     exit(1);
     }
     printf ("Digite o nome: ");
     gets(nome);

    //fread: file read, "lê arquivo"
    //sizeof(operador): é usado para  saber o tamanho de variáveis
    //sizeof serve tambem para garantir a portabilidade
     leitura = fread(&Tab[indice], sizeof(struct Agenda), 1, fp);

        while (leitura == 1){
            //faz a comparação com "strcmp" em todos os indices da estrutura nome por algo igual ao digitado
            //nome digita com a posição nome no indice x por exemplo (x é um numero)
            if (strcmp(nome, Tab[indice].nome) == 0 ){

            printf ("\nNome ......: %s\nTelefone ..: %s\n", Tab[indice].nome, Tab[indice].tel);

            //adiciona ao contador
            cont++;
            }
            indice++;//incrementa indice

            /*
            fread: Lê uma matriz de elementos a partir do fluxo e armazena-os no bloco de memória especificada por ptr.

            fread ( tabela, tamanho a ser lido, quantidade minima a ser contada, arquivo );

            */
            leitura = fread(&Tab[indice], sizeof(struct Agenda), 1, fp); //le novamento com um novo indice
        }
        //caso ocontador seja 0 retorna que não houve resultados.
        if(cont == 0){
                     printf("Nao ha contatos com este nome!\n");
                     }
        getch();
        fclose(fp);
   }

//função responsavel por listar o conteudo da agenda

void Listar(void){


    /* funciona como a função de pesquisa sem o strcmp */
int indice = 0, leitura;

    if ((fp = fopen("agenda.txt", "r")) == NULL)
    {
    printf ("O arquivo da lista não pode ser aberto!\n");
    printf ("Insira dados!\n");
    getch();
    exit(1);
    }

    leitura = fread(&Tab[indice], sizeof(struct Agenda), 1, fp);
   // fread lê e retorna a quantidade de itens ...

   while ( leitura == 1) {
      printf("\n Nome ......: %s",   Tab[indice].nome);
      printf("\n Telefone ..: %s",   Tab[indice].tel);
      printf("\n");
      indice++;
      leitura = fread(&Tab[indice], sizeof(struct Agenda), 1, fp);
      }
      printf(" \n\n %d Contatos salvos!\n", indice);
      getch();
      fclose(fp);
}

// Menu

void Menu(void){
    char op;
    do{
        system("cls"); //Limpa a tela
        printf("\n Escolha uma op%c%co \n",135, 198);
        printf("\n1 - Incluir\n2 - Listar\n3 - Ordenar\n4 - Pesquisar\n");
        printf("5 - Sair\n\n"); //Não seria necessario, mas por estetica coloquei
        op = getch();
            switch(op){
                case '1':
                     Inclusao();
                break;
                case '2':
                     Listar();
                break;
                case '3':
                     Ordenar();
                break;
                case '4':
                     Pesquisar();
                break;

                default: // por default qualquer tecla diferente das citadas faz o programa fechar
                exit(1);
            }
    }while (op < '5');

}

//Função para repetir a inclusão

char ValidaResp() {
   char op;
   do {
      printf(" \n Inserir novos dados? [S ou N] ? " );
      op = getch();
      printf("\n" );
   } while (op != 's' && op != 'n');
   return op;
}

Scripts recomendados

Balanceamento de parênteses utilizando Pilha

Fatorial de um número

Damas em C

Criando usuários através de arquivo texto

Informações do kernel


  

Comentários
[1] Comentário enviado por costa728 em 17/02/2017 - 00:11h

excelente funciona certinho no w10


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts