Tag: C

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 : , ,

Referências bibliográficas para C

Reference Style – All Levels

Beginner

Intermediate

Above Intermediate

+infos(lista completa): LINK

Tags : ,

Referências bibliográficas para C++

Introductory, with previous programming experience

  • C++ Primer * (Stanley Lippman, Josée Lajoie, and Barbara E. Moo) (updated for C++11) Coming at 1k pages, this is a very thorough introduction into C++ that covers just about everything in the language in a very accessible format and in great detail. The fifth edition (released August 16, 2012) covers C++11. [Review]
  • A Tour of C++ (Bjarne Stroustrup) The “tour” is a quick (about 180 pages and 14 chapters) tutorial overview of all of standard C++ (language and standard library, and using C++11) at a moderately high level for people who already know C++ or at least are experienced programmers. This book is an extended version of the material that constitutes Chapters 2-5 of The C++ Programming Language, 4th edition.
  • Accelerated C++ (Andrew Koenig and Barbara Moo) This basically covers the same ground as the C++ Primer, but does so on a fourth of its space. This is largely because it does not attempt to be an introduction to programming, but an introduction to C++ for people who’ve previously programmed in some other language. It has a steeper learning curve, but, for those who can cope with this, it is a very compact introduction into the language. (Historically, it broke new ground by being the first beginner’s book to use a modern approach at teaching the language.) [Review]
  • Thinking in C++ (Bruce Eckel) Two volumes; is a tutorial style free set of intro level books. Downloads: vol 1, vol 2. Unfortunately they’re marred by a number of trivial errors (e.g. maintaining that temporaries are automatically const), with no official errata list. A partial 3rdparty errata list is available at (http://www.computersciencelab.com/Eckel.htm), but it’s apparently not maintained.

* Not to be confused with C++ Primer Plus (Stephen Prata), with a significantly less favorable review.

Best practices

  • Effective C++ (Scott Meyers) This was written with the aim of being the best second book C++ programmers should read, and it succeeded. Earlier editions were aimed at programmers coming from C, the third edition changes this and targets programmers coming from languages like Java. It presents ~50 easy-to-remember rules of thumb along with their rationale in a very accessible (and enjoyable) style. For C++11 and C++14 the examples and a few issues are outdated and Effective Modern C++ should be preferred. [Review]
  • Effective Modern C++ (Scott Meyers) This is basically the new version of Effective C++, aimed at C++ programmers making the transition from C++03 to C++11 and C++14.
  • Effective STL (Scott Meyers) This aims to do the same to the part of the standard library coming from the STL what Effective C++ did to the language as a whole: It presents rules of thumb along with their rationale. [Review]

Intermediate

  • More Effective C++ (Scott Meyers) Even more rules of thumb than Effective C++. Not as important as the ones in the first book, but still good to know.
  • Exceptional C++ (Herb Sutter) Presented as a set of puzzles, this has one of the best and thorough discussions of the proper resource management and exception safety in C++ through Resource Acquisition is Initialization (RAII) in addition to in-depth coverage of a variety of other topics including the pimpl idiom, name lookup, good class design, and the C++ memory model.[Review]
  • More Exceptional C++ (Herb Sutter) Covers additional exception safety topics not covered inExceptional C++, in addition to discussion of effective object oriented programming in C++ and correct use of the STL. [Review]
  • Exceptional C++ Style (Herb Sutter) Discusses generic programming, optimization, and resource management; this book also has an excellent exposition of how to write modular code in C++ by using nonmember functions and the single responsibility principle. [Review]
  • C++ Coding Standards (Herb Sutter and Andrei Alexandrescu) “Coding standards” here doesn’t mean “how many spaces should I indent my code?” This book contains 101 best practices, idioms, and common pitfalls that can help you to write correct, understandable, and efficient C++ code. [Review]
  • C++ Templates: The Complete Guide (David Vandevoorde and Nicolai M. Josuttis) This is thebook about templates as they existed before C++11. It covers everything from the very basics to some of the most advanced template metaprogramming and explains every detail of how templates work (both conceptually and at how they are implemented) and discusses many common pitfalls. Has excellent summaries of the One Definition Rule (ODR) and overload resolution in the appendices. A second edition is scheduled for 2016. [Review]

Advanced

  • Modern C++ Design (Andrei Alexandrescu) A groundbreaking book on advanced generic programming techniques. Introduces policy-based design, type lists, and fundamental generic programming idioms then explains how many useful design patterns (including small object allocators, functors, factories, visitors, and multimethods) can be implemented efficiently, modularly, and cleanly using generic programming. [Review]
  • C++ Template Metaprogramming (David Abrahams and Aleksey Gurtovoy)
  • C++ Concurrency In Action (Anthony Williams) A book covering C++11 concurrency support including the thread library, the atomics library, the C++ memory model, locks and mutexes, as well as issues of designing and debugging multithreaded applications.
  • Advanced C++ Metaprogramming (Davide Di Gennaro) A pre-C++11 manual of TMP techniques, focused more on practice than theory. There are a ton of snippets in this book, some of which are made obsolete by typetraits, but the techniques, are nonetheless useful to know. If you can put up with the quirky formatting/editing, it is easier to read than Alexandrescu, and arguably, more rewarding. For more experienced developers, there is a good chance that you may pick up something about a dark corner of C++ (a quirk) that usually only comes about through extensive experience.

+infos(lista completa): LINK

Tags : ,

MOOC interessante sobre POO

Aqui está mais um MOOC interessante sobre POO, com o nome de CS101.2x Object-Oriented Programming

+infos: LINK

Tags : , ,

Allegro

allegro

O Allegro é uma biblioteca multi plataforma que permite usar rotinas relacionadas com gráficos, sons, entrada de dados e outros que estão relacionados com o desenvolvimento de video jogos em linguagens de baixo nivel como o C ou o C++

O Allegro é open source :)

+infos(oficial): https://www.allegro.cc/

Tags : , ,