Tag: linguagem C

parte 6 – várias funções em C para manipulação de ficheiros e estruturas dinâmicas

Assunto deste post: várias funções em C para manipulação de ficheiros (de texto para binários e de binários para texto e estruturas dinâmicas (lista ligada e vector dinâmico de estruturas)

//ficheiro parte1.c
#include "parte1Comum.h"

int menu(){
    int i;
    puts("1 - adiciona grupo");
    puts("2 - remove grupo");
    puts("3 - lista grupo");
    puts("4 - pesquisa grupo");
    puts("5 - ");
    puts("6 - ");
    puts("7 - carregar grupo de um ficheiro binario");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}


void main() {
    int escolha;
    pGrupo listaGrupo=NULL;
    pMesa listaMesa[TAM]={NULL};
    int totalMesas=0;
    int h, m, pessoas;
    char mesa[20];
   
     do{
         printf("\ntotal de mesas: %d\n\n", totalMesas);
        escolha = menu();
        switch(escolha){
            case 1: 
                    printf("\nA que horas e minutos vem a reserva? (formato h m)\n");
                    scanf(" %d", &h);
                    scanf(" %d", &m);
                    printf("\nQuantas pessoas?\n");
                    scanf(" %d", &pessoas);
                    printf("\nQual a mesa?\n");
                    scanf(" %99[^\n]", mesa);
                    adicionaGrupo(listaMesa[TAM], &totalMesas, &listaGrupo, h, m, pessoas, mesa);
                    break;
            case 2: break;
            case 3: 
                    listagemGrupo(listaGrupo);
                    break;
            case 4: break;
            case 5: break;
            case 6: break;
            case 7: break;
        }
    }while(escolha != 8);
    
}


//ficheiro parte1Comum.h
#ifndef PARTE1COMUM_H
#define PARTE1COMUM_H

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

#define TAM 20

typedef struct tipoA mesa, *pMesa;
typedef struct tipoB grupo, *pGrupo;

struct tipoA{
    char id[20];
    int conta, valorTot;
};

struct tipoB{
    struct hora{int h, m;} in, out;
    int num, valor;
    pMesa ptr;
    pGrupo prox;
};

pGrupo adicionaGrupo(pMesa v, int *tot, pGrupo *lista, int h, int m, int pessoas, char *idM);
void adicionaGrupoAux();
pGrupo listagemGrupo(pGrupo lista);

#endif /* PARTE1COMUM_H */


//ficheiro parte1Comum.c
#include "parte1Comum.h"
//funções

//receber um grupo: dados do grupo e preenhcer os dados da mesa

pGrupo adicionaGrupo(pMesa v, int *tot, pGrupo *lista, int h, int m, int pessoas, char *idM){

    printf("\nvamos la ver se apanho os dados\n");
    printf("%d\t%d\t%d\t%d\t%s\t", *tot, h ,m ,pessoas, idM);
    pGrupo novo;
    novo = malloc(sizeof(grupo));
     if(novo==NULL){
         printf("\nerro: nao foi possivel reservar memoria");
         return NULL;
     }else{
     if(*tot==0){
         //primeira reserva mesa
        novo->in.h = h;
        novo->in.m = m;
        novo->num = pessoas;
        novo->prox = NULL;
        (*tot)++;
        //v[0].id = idM;
        //strcpy(v[0].id, idM);
        printf("\n\n%s",v[0].id);
        
        return novo;
    }
    
    
    }
    return novo;
    free(novo);
}

pGrupo listagemGrupo(pGrupo lista){

    printf("entrei");
    
    return NULL;
}
Tags : , ,

parte 5 – gestão dinâmica de memória (listas ligadas a listas ligadas)

O caso de uma lista de disciplinas que tem alunos inscritos.. :) as disciplinas é uma lista ligada e os alunos inscritos também o são.. vamos ver como corre

//listas de listas (listas ligadas)
#include <stdio.h>
#include <stdlib.h>

#define TAM 3
#define TAMNOME 10

typedef struct pessoa aluno, *paluno; 
typedef struct disciplina aUC, *pUC; 

struct pessoa{s
    int nif;
    char nome[TAMNOME];
    paluno pseguinte;
};


struct disciplina{
    int numeroUC;
    char nomeUC[TAMNOME];
    pUC pUCseguinte;
    paluno lista;
};

int lista_vazia(paluno p, pUC puc);
int menu();
pUC adicionaUC(int *auxTUC, pUC p);
void listaUCs(pUC p, int totalUC);
pUC removerUC(int *auxTUC, pUC p);
paluno adicionaAluno(paluno pA, pUC pU);



int lista_vazia(paluno p, pUC puc){
    if(p==NULL && puc == NULL){
        return 1;
    }else{
        return 0;
    }
}

int menu(){
    int i;
    //printf("total UCs: %d", totalUCs)
    puts("1 - adiciona UC");
    puts("2 - remove UC"); //last
    puts("3 - lista UCs");
    puts("4 - adiciona aluno a UC");
    puts("5 - remove aluno a UC"); //last
    puts("6 - lista UC de aluno");
    puts("7 - ");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}

pUC removerUC(int *auxTUC, pUC p){
    int retirarUC;
    pUC atual, anterior=NULL;
    
    atual = p;
    
    if(p==NULL){
        printf("\nerro: nao existe nada para remover");
        return p;
    }else{
        printf("\nqual o nif da UC a remover?\n");
        scanf("%d", &retirarUC);
        
        while(atual != NULL && atual->numeroUC != retirarUC){
            anterior = atual;
            atual= atual->pUCseguinte;
        }
        if(anterior == NULL){
            p = atual->pUCseguinte;
            (*auxTUC)--;
        }else{
            anterior->pUCseguinte = atual->pUCseguinte;
            (*auxTUC)--;
        }
        }
    free(atual);
    return p;
}

paluno adicionaAluno(paluno pA, pUC pU){
    
    
    
    

    return pA;
}


pUC adicionaUC(int *auxTUC, pUC p){
    int auxiliar;
    pUC novo, cursor;
    
    novo = malloc(sizeof(aUC));
    if(novo == NULL){
        printf("erro: nao e possivel alocar memoria para a UC");
        return p;
    }else{
    
    if(*auxTUC >= TAM){
        printf("erro: nao e possivel adicionar mais UC\n");
        free(novo);
        return p;
    }else{
        printf("Qual o numero da nova UC?\n");
        scanf("%d", &novo->numeroUC);
        printf("Qual o nome da nova UC?\n");
        scanf(" %99[^\n]", novo->nomeUC);
        novo->pUCseguinte = NULL;
        novo->lista = NULL;
        
        if(p==NULL){    
            p=novo;
            (*auxTUC)++;
            return p;
        }else{
            cursor=p;
            while(cursor->pUCseguinte != NULL){
                cursor=cursor->pUCseguinte;
                }
                cursor->pUCseguinte = novo;
                (*auxTUC)++;
                return p;
        }
    }
    }
    free(novo);
}

void listaUCs(pUC p, int totalUC){

    if(p==NULL){
        printf("\nerro: nao tem nada para listar de UCs");
    }else{
        printf("\nlistagem das %d UCs:\n", totalUC);
        while(p!=NULL){
            printf("%d\t%s\n", p->numeroUC, p->nomeUC);
            p=p->pUCseguinte;
        }
    }
}



int main() {
    int escolha, totalUC=0;
    paluno listaA=NULL;
    pUC listaUC=NULL;
    
    if(lista_vazia(listaA, listaUC)==1){
    do{
        escolha = menu();
        switch(escolha){
            case 1: listaUC=adicionaUC(&totalUC, listaUC); break;
            case 2: listaUC=removerUC(&totalUC, listaUC); break;
            case 3: listaUCs(listaUC, totalUC);
            case 4: listaA=adicionaAluno( listaA, listaUC);break;
            case 5: break;
            case 6: break;
            case 7: break;
            case 8: break;
        }
    }while(escolha != 8);
    }else{
        printf("nao foi possivel inicializar!");
    }
    
    
    return 0;
}


e ficou incompleto..

ajudas:
LINK1

Tags : , ,

parte 5 – gestão dinâmica de memória (lista duplamente ligada)

As listas duplamente ligadas pressupõem sempre que cada nó tem sempre dois ponteiros: um para o próximo nó e outro para o nó anterior

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

#define TAM 100

typedef struct elemento pessoa, *pelemento;

struct elemento{
    char nome[TAM];
    int idade;
    pelemento prox;
    pelemento antes;
};

int lista_vazia(pelemento p);
void mostra_elemento(pelemento p);
pelemento adiciona_elemento(pelemento p);
pelemento elimina_elemento(pelemento p);
void pesquisa_elemento(pelemento p);
void guarda_lista(pelemento p);
pelemento ler_lista(pelemento p);

int menu(){
    int i;
    puts("1 - adiciona elemento");
    puts("2 - elimina elemento");
    puts("3 - mostra a lista elementos");
    puts("4 - pesquisar na lista");
    puts("5 - esvaziar a lista");
    puts("6 - obter lista de um ficheiro");
    puts("7 - guardar lista de um ficheiro");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}

int lista_vazia(pelemento p){
    if(p==NULL){
        return 1;
    }else{
        return 0;
    }
}

pelemento elimina_elemento(pelemento p){
    pelemento aux=NULL;
    char apagar[TAM];

    if(p == NULL){
        printf("erro: nao existem elementos para elimninar");
        return p;
    }else{
    aux=p;
    printf("qual o nome que quer apagar?\n");
    scanf(" %99[^\n]", apagar);
    printf("vou procurar: %s\n", apagar);
    
    while(aux != NULL && strcmp(aux->nome, apagar) != 0){
        aux=aux->prox;
    }
    //nao encontrou
    if(aux == NULL){
        return p;
    }else{ 
       
    //primeiro elemento
    if(aux == p){
        printf("encontrei: vou apagar1\n");
        p=aux->prox;
        if(p != NULL){
            p->antes = NULL;
        }
    }else{
        printf("nao e o primeiro - encontrei: vou apagar2\n");
        aux->antes->prox = aux->prox;
        if(aux->prox != NULL){
            aux->prox->antes = aux->antes;
        }
    }
    }
    }
    free(aux);
    return p;
}


pelemento adiciona_elemento(pelemento p){
    pelemento novo, aux;
    novo = malloc(sizeof(pessoa));
   
    if(novo == NULL){
        printf("erro: na alocacao de memoria\n");
        return p;
    }
        
    if(p==NULL){ //se a lista estiver vazia
    //a lista está vazia
        printf("Qual o nome? ");
        scanf(" %99[^\n]", novo->nome);
        printf("Qual a idade? ");
        scanf("%d", &novo->idade);
        novo->prox=NULL;
        p=novo;
        
        return p;
    }else{
    //se a lista nao estiver vazia
        printf("Qual o nome?2 ");
        scanf(" %99[^\n]", novo->nome);
        printf("Qual a idade?2 ");
        scanf("%d", &novo->idade);
        //mas for o segundo elemento
        if(p->prox==NULL){
            p->prox=novo;
            novo->antes=p;
            novo->prox=NULL;
            return p;
        }else{
            aux = p;
            //se nao for o primeiro elemento
            while(aux->prox != NULL){
                aux=aux->prox;
            }
            novo->prox = aux->prox; //aponta para null ?? nao percebi
            novo->antes = aux;
            aux->prox = novo; 
            return p;
        }
    }
    free(novo);
    return p;
}

void mostra_elemento(pelemento p){

    if(p==NULL){
        printf("\nerro: lista esta vazia\n");
    }else{
        printf("\nLista de elementos:\n");
        while(p != NULL){       
            printf("%s\t%d\t\n", p->nome, p->idade);
            p = p->prox;
        }
    }
}

void pesquisa_elemento(pelemento p){
    pelemento aux;
    char apagar[TAM]; 
    
    if(p==NULL){
        printf("lista vazia\n");
    }else{
        aux=p;
        printf("Qual o nome do elemento que quer procurar?\n");
        scanf(" %99[^\n]", apagar);
        
        while(aux != NULL){
            if(strcmp(aux->nome, apagar)==0){
                printf(".........................encontrei\n");
                printf("%s\t%s", aux->nome, apagar);
            }
            aux=aux->prox;
        }
    }
}

void guarda_lista(pelemento p){
    FILE *f;
    pelemento aux;
    
    f = fopen("gd2.bin","wb");
    if(f == NULL){
        printf("nao foi possivel executar a operacao");
    }else{
        aux=p;
        while(aux != NULL){
            fwrite(aux,sizeof(pessoa),1,f);
            aux=aux->prox;
        }
    }
    printf("\nLista guardada\n");
    fclose(f);
}

pelemento ler_lista(pelemento p){
    FILE *f;
    pelemento novo=NULL;
    
   f = fopen("gd2.bin","rb");
   if(f == NULL){
        printf("nao foi possivel executar a operacao");
        return p;
    }else{
            while(feof(f) == 0){
                novo=malloc(sizeof(pessoa));
                fread(novo,sizeof(pessoa),1,f);
                novo->prox = p;
                p = novo;    
            }
        }
   
   free(novo);
   fclose(f);
   return p;
}
int main() {
    int escolha;
    pelemento lista = NULL; //1) criar a lista
    
    if(lista_vazia(lista)==1){
    do{
        escolha = menu();
        switch(escolha){
            case 1: lista = adiciona_elemento(lista); break;
            case 2: lista = elimina_elemento(lista);break;
            case 3: mostra_elemento(lista); break;
            case 4: pesquisa_elemento(lista); break;
            case 5: break;
            case 6: lista = ler_lista(lista); break;
            case 7: guarda_lista(lista); break;
            case 8: break;
        }
    
    }while(escolha != 8);
    }else{
        printf("nao foi possivel inicializar!");
    }
    return 0;
}


Tags : , ,

parte 5 – gestão dinâmica de memória (lista ligada)

Principal vantagem de se usar lista ligada: flexibilidade

O acesso é sequencial, em que cada estrutura contém: os campos e um ponteiro para o próximo elemento da lista
operações com listas ligadas:
1) criar a lista
2) verificar se está vazia
3) pesquisar/lustar
4) adicionar um elemento
5) retirar um elemento
6) destruir a lista

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

#define TAM 100


typedef struct objeto livro, *plivro;

struct objeto{
    char titulo[TAM], autor[TAM];
    int cota;
    plivro prox; //ponteiro para o proximo elemento da lista
};


//
int lista_vazia(plivro p);
plivro insere_inicio(plivro p);
plivro insere_final(plivro p);
plivro insere_ordenado(plivro p);
void mostra(plivro p);
plivro elimina(plivro p);
void destruir(plivro p);
plivro ler_ficheiro(plivro p);
void guarda_ficheiro(plivro p);

//2) verificar se está vazia
int lista_vazia(plivro p){
    if(p==NULL){
        return 1;
    }else{
        return 0;
    }
}

int menu(){
    int i;
    puts("1 - adiciona livro - inicio");
    puts("2 - adiciona livro - final");
    puts("3 - adiciona livro - ordenado");
    puts("4 - elimina livro");
    puts("5 - lista livros");
    puts("6 - esvaziar a lista");
    puts("7 - carregar lista de um ficheiro");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}

plivro insere_inicio(plivro p){
    plivro novo;
    novo = malloc(sizeof(livro)); //aponta para um qq espaço em memória
    
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
               
        //surge agora uma parelha obrigatória
        novo->prox=p; //aponto o novo para a primeira posição
        p=novo; //a primeira posição é o novo
                
        return p;
    }
    free(novo);
}

plivro insere_final(plivro p){
    plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio, insere no inicio
        if(p == NULL){
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
            while(aux->prox != NULL){
                aux = aux->prox;
            }
            aux->prox = novo;
        }
        return p;
    }
    free(novo);
}

plivro insere_ordenado(plivro p){
     plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio
        if(p == NULL || strcmp(novo->titulo, p->titulo) < 0){
        //if(p == NULL || novo->cota < p->cota){
            novo->prox = p;
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
             while(aux->prox != NULL && strcmp(novo->titulo, aux->titulo) >0){
             //while(aux->prox != NULL && novo->cota > aux->cota){
                aux = aux->prox;
            }
            novo->prox = aux->prox;
            aux->prox = novo;
        }
        return p;
    }
    
    free(novo);

}


void mostra(plivro p){
    
    if(p==NULL){
        printf("\nerro: lista vazia, sem elementos para listar!\n\n");
    }else{
    while(p!=NULL){
        printf("%s\t%s\t%d\n", p->titulo, p->autor, p->cota);
        p = p->prox;
    }
    }
}


plivro elimina(plivro p){
    int apaga;
    plivro atual, anterior=NULL;
    
    atual= p;
    
    if(p==NULL){
        printf("\nerro: lista vazia sem informacao\n");
        return p;
    }else{
        mostra(p);
        printf("qual o livro e cota que pretende eliminar?");
        scanf("%d", &apaga);
        while(atual!=NULL && atual->cota != apaga){
            anterior = atual;
            atual = atual->prox;
        }
        if(anterior ==NULL){
            p = atual->prox;
        }else{
            anterior->prox = atual->prox;
        }
    free(atual);
    return p;
    }
}

void destruir(plivro p){
    plivro aux;
    
    if(p==NULL){
        printf("\nerro: nada para apagar!\n");
    }
    
    while(p!=NULL){
        aux = p;
        p=p->prox;
        free(aux);
    }

}

plivro ler_ficheiro(plivro p){
    FILE *f;
    plivro novo=NULL;
        
    if(p!=NULL){
        printf("\nerro: lista ja preenchida\n");
        return p;
    }else{
    
    f = fopen("listaLivros.dat", "rb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return p;
    }else{
       
       while(feof(f) == 0){
            novo = malloc(sizeof(livro));
            fread(novo, sizeof(livro), 1, f);
            novo->prox = p;
            p = novo; //erro aqui
        }
    }
    }
    free(novo);
    fclose(f);
    return p;
}

void guarda_ficheiro(plivro p){
    FILE *f;
    
    f = fopen("listaLivros.dat", "wb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
        while(p != NULL){
        fwrite(p, sizeof(livro), 1, f);
        p=p->prox;
        }
        fclose(f);
        free(p);
    }
}


int main() {
    int escolha;
    plivro lista = NULL; //1) criar a lista
    
    if(lista_vazia(lista)==1){
    do{
        escolha = menu();
        switch(escolha){
            case 1: lista = insere_inicio(lista); break;
            case 2: lista = insere_final(lista); break;
            case 3: lista = insere_ordenado(lista); break;
            case 4: lista = elimina(lista); break;
            case 5: mostra(lista); break;
            case 6: destruir(lista); break;
            case 7: lista= ler_ficheiro(lista); break;
        }
    
    }while(escolha != 8);
    }else{
        printf("nao foi possivel inicializar!");
    }

    guarda_ficheiro(lista);
    return 0;
}



Tags : , ,

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

Tags : , ,

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;
}
Tags : , ,

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;
}
Tags : , ,

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;
}



Tags : , ,

parte 2 – ponteiros (ou apontador)

notas acerca dos ponteiros, ou apontadores (aceder indirectamente a variáveis, através da sua localização):

Utilizar ponteiros para estabelecer a comunicação entre funções, se pretendo alterar o valor de uma variável dentro de uma função, tenho que passar como argumento um ponteiro para a variável e não uma copia do seu valor;

declaração: tipo *nome_ptr;

inicialização: tipo *nome_ptr = %qualquercoisaInt;

dois operadores:
& : obter o endereço de uma variável
* : aceder à variável para onde um ponteiro aponta

= : permite a atribuição entre ponteiros

notasM: quando faço p = &j; //estou a alterar o valor que está em j

notas acerca dos arrays (vetores):

[propriedade 1]

num array uni-dimensional a[i] ou *(a+i) é a mesma coisa. representam o primeiro elemento

[propriedade 2]

aritmética -> (p+i) ou (p-i) estou a deslocar posições dentro de um array

p+i equivalente a &a[i]

a[i] equivalente *(a+i)

declaração de uma função que recebe um vetor como argumento:
tipo funcao(tipo_de_vetor vetor[dimensao])
tipo funcao(tipo_de_vetor vetor[])
tipo funcao(tipo_de_vetor *vetor)

o uso da função é feito com nome do vector APENAS!

STRINGS

puts() //escreve strings <=> putchar()

strlen() //conta caracteres

strcat() //junta strings

tentar clearerr(stdin);

ao invés de usarmos array de caracteres (char st[TAM]) podemos usar ponteiro para carácter (char *p), vantagem? espaço em memória! Mas só funciona se as strings forem constantes.

como resolver isto?

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

#define TAM 4

void mostra1(char **vB){

    for(int i=0; i<TAM; i++){
        puts(vB[i]);
    }

}

void mostra2(char *vA){

    for(int i=0; i<TAM; i++){
        //puts( vA[i]);
        //printf("%d\n", vA[i]);
    }

}

int main() {
    
    char vetorA[TAM][10]={"pedro","andre","maria","carlos"};
    char *vetorB[]={"portugal","espanha","marrocos","franca"};

    mostra1(vetorB);
    puts(vetorA[1]);
    mostra2(vetorA[TAM]);
    
    return (0);
}


ainda sobre o strcmp e para relembrar
se == 0, significa que são iguais
se < 0, a primeira é mais pequena que a segunda se > 0, a segunda é maior do que a segunda

Tags : , ,