Agenda eletronica com banco de dados em arquivo texto
Publicado por Allan Barcelos (última atualização em 14/08/2011)
[ Hits: 16.148 ]
Homepage: https://barcelos.dev
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.
/*
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;
}
Calcular dia da semana a partir de uma data sugerida
Regra de Horner para cálculo do polinômio
Manipulação de letras maiusculas e minusculas
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Atualizar Linux Mint 22.2 para 22.3 beta
Jogar games da Battle.net no Linux com Faugus Launcher
Como fazer a Instalação de aplicativos para acesso remoto ao Linux
Conky, alerta de temperatura alta (10)
Assisti Avatar 3: Fogo e Cinzas (3)
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (42)









