brhue 7 Denunciar post Postado Fevereiro 1, 2014 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
reebr 94 Denunciar post Postado Fevereiro 2, 2014 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 ReleaseExecuting 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
brhue 7 Denunciar post Postado Fevereiro 2, 2014 @ 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 ReleaseExecuting 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
reebr 94 Denunciar post Postado Fevereiro 3, 2014 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
_Isis_ 202 Denunciar post Postado Fevereiro 3, 2014 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
brhue 7 Denunciar post Postado Fevereiro 3, 2014 @ 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. ------------------------------------------------------------------------------------------------------------------------------------------------ @@_Isis_ 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