Agenda eletronica com banco de dados em arquivo texto
Publicado por Allan Barcelos (última atualização em 14/08/2011)
[ Hits: 16.080 ]
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;
}
Ler N números e ver qual é o maior
Imprime a soma dos numeros positivos e negativos
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Novos apps de produtividade, avanços em IA e distros em ebulição agitam o universo Linux
Como instalar o repositório do DBeaver no Ubuntu
Como instalar o Plex Media Server no Ubuntu
Digitando underscore com "shift" + "barra de espaços"
Como ativar a lixeira e recuperar aquivos deletados em um servidor Linux
Como mudar o nome de dispositivos Bluetooth via linha de comando
Linux é a solução para o fim do Windows10? (3)
Assinador JNLP do Site Portal da Nota Fiscal Eletrônica (0)
Programa fora de escala na tela do pc (29)









