Day: August 29, 2018
parte 4 – ficheiros (ainda…)
falta rever a situação de:
ftell –> exemplo ftell(f)/sizeof(struct pessoa) -> diz-me por exemplo quantas pessoas estão no ficheiro
fseek
SEEK_CUR
SEEK_END
SEEK_SET
parte 4 – ficheiros (texto)
O trabalho com ficheiros de texto já é um pouco diferente
notas acerca dos ficheiros de texto:
leitura de espaços vazios ou tabs é a mesma coisa
#include <stdio.h> #include <stdlib.h> /* //exemplo do ficheiro de texto Ana Mendes 3 5 7 12 20 1 3 Marcia Dantas 1 2 3 4 5 6 7 */ int main() { FILE *f; char nome[100]; f = fopen("ex3_dados.txt", "r"); int i, lista[7]; if(f != NULL){ while(feof(f) == 0){ fscanf(f, " %[^\n] ", nome); printf("%s \n", nome); for(i=0; i< 7; i++){ fscanf(f, "%d", &lista[i]); } for(i=0; i< 7; i++){ printf("%d ", lista[i]); } //printf("\n"); putchar('\n'); } }else{ printf("\n o ficheiro nao foi encotnrado!"); } return 0; }
Para trabalhar com o exemplo do banco e clientes, mas desta vez com ficheiros de texto, sem guardar o total de registos. Não consegui resolver a situação de ler ficheiros como deve ser..
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TAM 5 /* //exemplo do conteudo do ficheiro de texto nome: pedro Nº conta: 1 Saldo: 100 */ typedef struct dados{ char numeroConta[15]; char nome[50]; int montante; } cliente; int menu(){ int i; puts("1 - adiciona cliente"); puts("2 - elimina cliente"); puts("3 - lista clientes"); puts("4 - mostra mais rico"); puts("5 - terminar"); puts("Escolha uma opcao: "); do{ scanf(" %d", &i); }while(i <0 || i >5); return i; } cliente escreve_cliente(){ cliente t; printf("Qual o numero da conta?"); scanf(" %14s", t.numeroConta); printf("Qual o nome?"); scanf(" %99[^\n]", t.nome); printf("Qual o montante?"); scanf("%d", &(t.montante)); return t; } void adiciona_cliente(cliente tabC[], int *totalC){ if(*totalC>=TAM){ printf("tabela de cliente cheia"); }else{ tabC[*totalC] = escreve_cliente(); (*totalC)++; } } void mostra_todos(cliente tab[], int totalC){ if(totalC==0){ printf("nao existem clientes\n"); }else{ for(int i=0; i< totalC; i++){ printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante); } } } void procura_mais_rico(cliente tab[], int totalC){ cliente maiorT; int aux=0, i=0; if(totalC==0){ printf("nao existem clientes\n"); }else{ maiorT.montante = tab[i].montante; for(; i< totalC; i++){ if(tab[i].montante > maiorT.montante ){ aux = i; } } printf("\no maior vem %d:\n" , aux); printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante); } } void elimina_cliente(cliente tab[], int *totalC){ char st[15]; int i; printf("Qual o numero da conta a eliminar? (%d)", *totalC); scanf(" %14s", st); if(totalC<0){ printf("nao existem clientes. nao se pode eliminar nada\n"); }else{ for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei ; if(i==*totalC){ printf("cliente nao existe\n"); }else{ tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual (*totalC)--; } } } void guarda_dados_texto(cliente *b, int total){ FILE *f; f = fopen("bancoBinario2.txt", "wt"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return; }else{ for(int i=0; i < total; i++){ fprintf(f, "nome: %s\tN.conta: %s\tSaldo: %d\n", b[i].nome, b[i].numeroConta, b[i].montante); } fclose(f); } } int ler_dados_texto(cliente *b){ FILE *f; int total=0; f = fopen("bancoBinario2.txt", "r"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return 0; }else{ while(feof(f) == 0){ printf("\nvou ler"); fscanf(f, " %[^\n] %[^\n] %[^\n]", b[total].nome, b[total].numeroConta, &b[total].montante); total++; } fclose(f); return total; } } int main() { printf("estruturas\n"); int totalClientes=0, escolha; cliente Banco[TAM]; totalClientes = ler_dados_texto(Banco); printf("\n\n%d\n\n", totalClientes); do{ escolha = menu(); switch(escolha){ case 1: adiciona_cliente(Banco,&totalClientes); break; case 2: elimina_cliente(Banco,&totalClientes); break; case 3: mostra_todos(Banco,totalClientes); break; case 4: procura_mais_rico(Banco,totalClientes); break; } }while(escolha != 5); guarda_dados_texto(Banco, totalClientes); return 0; }
parte 4 – ficheiros (binários)
Existem dois tipos de ficheiros: binários e de texto
se for feito uso de um ficheiro binário é recomendável que se guarde o numero de estruturas logo no inicio do ficheiro e de seguida as estruturas
versão light onde indico qual o numero de estruturas que existem e que vão ser guardadas no ficheiro
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TAM 5 typedef struct dados{ char numeroConta[15]; char nome[50]; int montante; } cliente; int menu(){ int i; puts("1 - adiciona cliente"); puts("2 - elimina cliente"); puts("3 - lista clientes"); puts("4 - mostra mais rico"); puts("5 - terminar"); puts("Escolha uma opcao: "); do{ scanf(" %d", &i); }while(i <0 || i >5); return i; } cliente escreve_cliente(){ cliente t; printf("Qual o numero da conta?"); scanf(" %14s", t.numeroConta); printf("Qual o nome?"); scanf(" %99[^\n]", t.nome); printf("Qual o montante?"); scanf("%d", &(t.montante)); return t; } void adiciona_cliente(cliente tabC[], int *totalC){ if(*totalC>=TAM){ printf("tabela de cliente cheia"); }else{ tabC[*totalC] = escreve_cliente(); (*totalC)++; } } void mostra_todos(cliente tab[], int totalC){ if(totalC==0){ printf("nao existem clientes\n"); }else{ for(int i=0; i< totalC; i++){ printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante); } } } void procura_mais_rico(cliente tab[], int totalC){ cliente maiorT; int aux=0, i=0; if(totalC==0){ printf("nao existem clientes\n"); }else{ maiorT.montante = tab[i].montante; for(; i< totalC; i++){ if(tab[i].montante > maiorT.montante ){ aux = i; } } printf("\no maior vem %d:\n" , aux); printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante); } } void elimina_cliente(cliente tab[], int *totalC){ char st[15]; int i; printf("Qual o numero da conta a eliminar? (%d)", *totalC); scanf(" %14s", st); if(totalC<0){ printf("nao existem clientes. nao se pode eliminar nada\n"); }else{ for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei ; if(i==*totalC){ printf("cliente nao existe\n"); }else{ tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual (*totalC)--; } } } void guarda_dados_binario(cliente *b, int totalC){ FILE *f; f = fopen("bancoBinario.bin", "wb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return; }else{ fwrite(&totalC, sizeof(int), 1, f); fwrite(b, sizeof(cliente), totalC, f); fclose(f); } } int ler_dados_binario(cliente *b){ FILE *f; int total; f = fopen("bancoBinario.bin", "rb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return 0; }else{ fread(&total, sizeof(int), 1, f); fread(b, sizeof(cliente), total, f); fclose(f); return total; } } int main() { printf("estruturas\n"); int totalClientes=0, escolha; cliente Banco[TAM]; totalClientes = ler_dados_binario(Banco); do{ escolha = menu(); switch(escolha){ case 1: adiciona_cliente(Banco,&totalClientes); break; case 2: elimina_cliente(Banco,&totalClientes); break; case 3: mostra_todos(Banco,totalClientes); break; case 4: procura_mais_rico(Banco,totalClientes); break; } }while(escolha != 5); guarda_dados_binario(Banco, totalClientes); return 0; }
versão hardcore onde NAO indico qual o numero de estruturas que existem e que vão ser guardadas no ficheiro
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TAM 5 typedef struct dados{ char numeroConta[15]; char nome[50]; int montante; } cliente; int menu(){ int i; puts("1 - adiciona cliente"); puts("2 - elimina cliente"); puts("3 - lista clientes"); puts("4 - mostra mais rico"); puts("5 - terminar"); puts("Escolha uma opcao: "); do{ scanf(" %d", &i); }while(i <0 || i >5); return i; } cliente escreve_cliente(){ cliente t; printf("Qual o numero da conta?"); scanf(" %14s", t.numeroConta); printf("Qual o nome?"); scanf(" %99[^\n]", t.nome); printf("Qual o montante?"); scanf("%d", &(t.montante)); return t; } void adiciona_cliente(cliente tabC[], int *totalC){ if(*totalC>=TAM){ printf("tabela de cliente cheia"); }else{ tabC[*totalC] = escreve_cliente(); (*totalC)++; } } void mostra_todos(cliente tab[], int totalC){ if(totalC==0){ printf("nao existem clientes\n"); }else{ for(int i=0; i< totalC; i++){ printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante); } } } void procura_mais_rico(cliente tab[], int totalC){ cliente maiorT; int aux=0, i=0; if(totalC==0){ printf("nao existem clientes\n"); }else{ maiorT.montante = tab[i].montante; for(; i< totalC; i++){ if(tab[i].montante > maiorT.montante ){ aux = i; } } printf("\no maior vem %d:\n" , aux); printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante); } } void elimina_cliente(cliente tab[], int *totalC){ char st[15]; int i; printf("Qual o numero da conta a eliminar? (%d)", *totalC); scanf(" %14s", st); if(totalC<0){ printf("nao existem clientes. nao se pode eliminar nada\n"); }else{ for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei ; if(i==*totalC){ printf("cliente nao existe\n"); }else{ tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual (*totalC)--; } } } void guarda_dados_binario(cliente *b, int total){ FILE *f; f = fopen("bancoBinario2.bin", "wb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return; }else{ fwrite(b, sizeof(cliente), total, f); fclose(f); } } int ler_dados_binario(cliente *b){ FILE *f; int total=0; cliente aux; f = fopen("bancoBinario2.bin", "rb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return 0; }else{ fread(&aux, sizeof(cliente), 1, f); while(feof(f) == 0){ b[total++]= aux; fread(&aux, sizeof(cliente), 1, f); } fclose(f); return total; } } int main() { printf("estruturas\n"); int totalClientes=0, escolha; cliente Banco[TAM]; totalClientes = ler_dados_binario(Banco); do{ escolha = menu(); switch(escolha){ case 1: adiciona_cliente(Banco,&totalClientes); break; case 2: elimina_cliente(Banco,&totalClientes); break; case 3: mostra_todos(Banco,totalClientes); break; case 4: procura_mais_rico(Banco,totalClientes); break; } }while(escolha != 5); guarda_dados_binario(Banco, totalClientes); return 0; }
parte 3 – estruturas
notas acerca das estruturas:
criar um novo tipo struct dados: 1º criar as variáveis, 2º declarar as variáveis
1º criar as variáveis
struct dados { char nome[TAM]; char nconta[15]; int montate; };
2º declarar as variáveis
struct dados m;
ou
Cliente b;
para aceder aos campos faz-se uso do ponto final -> m.nome
associar um novo nome à estrutura: typedef declaração-do-tipo sinónimo;
typdef struct dados cliente;
estruturas encadeadas:
struct data{ int dia, mes, ano; }; struct dados{ char nome[TAM]; char nconta[15]; int montate; };
notas acerca das estruturas:
operador de atribuição só para estruturas do mesmo tipo (faz copia em bloco ao invés de um a um)
comparação é sempre feita campo a campo
ponteiros e estruturas (*p).c equivalente a p->c
construir um vetor de estururas, struct dados clientes[30];
para calcula a dimensão de um vetor faz-se uso do sizeof(clientes) ou sizeof(struct dados) *30
exemplo clássico de trabalho com estruturas, sendo que o eliminar foi construído da seguinte forma:
mover o ultimo para a posição a eliminar e actualizar o total de posições
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TAM 5 typedef struct dados{ char numeroConta[15]; char nome[50]; int montante; } cliente; int menu(){ int i; puts("1 - adiciona cliente"); puts("2 - elimina cliente"); puts("3 - lista clientes"); puts("4 - mostra mais rico"); puts("5 - terminar"); puts("Escolha uma opcao: "); do{ scanf(" %d", &i); }while(i <0 || i >5); return i; } cliente escreve_cliente(){ cliente t; printf("Qual o numero da conta?"); scanf(" %14s", t.numeroConta); printf("Qual o nome?"); scanf(" %99[^\n]", t.nome); printf("Qual o montante?"); scanf("%d", &(t.montante)); return t; } void adiciona_cliente(cliente tabC[], int *totalC){ if(*totalC>=TAM){ printf("tabela de cliente cheia"); }else{ tabC[*totalC] = escreve_cliente(); (*totalC)++; } } void mostra_todos(cliente tab[], int totalC){ if(totalC==0){ printf("nao existem clientes\n"); }else{ for(int i=0; i< totalC; i++){ printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante); } } } void procura_mais_rico(cliente tab[], int totalC){ cliente maiorT; int aux=0, i=0; if(totalC==0){ printf("nao existem clientes\n"); }else{ maiorT.montante = tab[i].montante; for(; i< totalC; i++){ if(tab[i].montante > maiorT.montante ){ aux = i; } } printf("\no maior vem %d:\n" , aux); printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante); } } void elimina_cliente(cliente tab[], int *totalC){ char st[15]; int i; printf("Qual o numero da conta a eliminar? (%d)", *totalC); scanf(" %14s", st); if(totalC<0){ printf("nao existem clientes. nao se pode eliminar nada\n"); }else{ for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei ; if(i==*totalC){ printf("cliente nao existe\n"); }else{ tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual (*totalC)--; } } } int main() { printf("estruturas\n"); int totalClientes=0, escolha; cliente Banco[TAM]; do{ escolha = menu(); switch(escolha){ case 1: adiciona_cliente(Banco,&totalClientes); break; case 2: elimina_cliente(Banco,&totalClientes); break; case 3: mostra_todos(Banco,totalClientes); break; case 4: procura_mais_rico(Banco,totalClientes); break; } }while(escolha != 5); return 0; }