1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

usar realloc e malloc em C#

Discussão em 'Programação' iniciada por Lbboy, 28 de Abril de 2009. (Respostas: 8; Visualizações: 2892)

  1. Lbboy

    Lbboy Power Member

    Tenho o seguinte codigo em c a funcionar exepto a parte de apagar a matricula.. mas essa parte é opcional por isso n interessa

    como disse o programa funciona..mas tenho que entregar o trabalho usando realloc e mallocs ( memoria dinamica, coisa que n fiz nem tou a ver como implementar neste codigo)

    agradecia uma ajuda :P

    retirado do pdf-->

    2) O programa principal deverá permitir a escolha das seguintes opções (utilize a
    instrução switch):
    1. Inserir registo. Deverá solicitar a introdução da matrícula e o nome do
    proprietário.
    2. Imprimir todos os registos no "standard output".
    3. Apagar registo.
    2.1 - Implemente o menu principal do programa e as opções 1 e 2. A lista deverá ser
    armazenada num bloco de memória alocado dinamicamente e cujo tamanho deverá
    crescer à medida que são inseridos registos (use a função realloc()).
    Nota: na opção 2, os registos cujo campo "apagado" tenha valor diferente de 0 não
    deverão ser impressos.

    ---------------------------------------------------------------------------------
    Código:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define SIZE 80
    
    typedef struct veiculos
    {
    char matricula[6];
    char proprietario[SIZE];
    char apagado;
    } veiculo_t;
    
    int menu();
    
    veiculo_t veiculo();
    
    void inserir_registo();
    void registos();
    void apagar_registo();
    
    int main()
    {
    
    int op;
        
            while(1)
        {
            op=menu();
    
        switch(op)
        {
        case 1:system("cls");
                inserir_registo();
                break;
        case 2:system("cls");
                registos();
                break;
        case 3:system("cls");
                apagar_registo();
                break;
        case 0:system("cls");
                exit(0);
                break;
        default: printf("ERRO: Opcao mal Escolhida\n");
                getchar();
    
        }
    
    }
    }
    
    int menu()
    {
    int op;
    system("cls");
    
        printf("\n\t\t\t\t MENU");
        printf("\n\n\t\t 1 - Inserir Registo");
        printf("\n\t\t 2 - Listar todos os registos");
        printf("\n\n\t\t 3 - Apagar Registo");
        printf("\n\n\t\t 0-Sair");
        printf("\n\n\t\t opcçao: ");
        
        scanf("%d",&op);
        getchar();
        
    return(op);    
    }
    
    veiculo_t veiculo()
    {
    char temp[8];
    veiculo_t registo;
    printf("\t\tREGISTO:");
    printf("\n\n\tInsira a matricula (EX:1111AA) do Automovel: ");
    fgets(temp,8,stdin);
    memcpy(registo.matricula,temp,6);
    printf("\n\tInsira o Nome do proprietário: ");
    fgets(registo.proprietario,80,stdin);
    registo.apagado='0';
    return(registo);
    }
    
    void inserir_registo()
    {
    veiculo_t registo;
    FILE *fa;
    
    fa=fopen("regist.bin","ab+");
    if(fa==NULL)
    {
        printf("ERRO: O Ficheiro não existe\n");
        exit(0);
    }
    registo=veiculo();
    
    fwrite(&registo,sizeof(veiculo_t),1,fa);
    fclose(fa);
    }
    
    void registos()
    {
    veiculo_t registo;
    FILE *fa;
    int i=1;    
    
        fa=fopen("regist.bin","rb");
        if(fa==NULL)
    {
        printf("ERRO: O Ficheiro não existe\n");
        exit(0);
    }
    
    while(fread(&registo,sizeof(veiculo_t),1,fa)!= 0)
    {
        if(registo.apagado=='0')
        {
            system("cls");
            fwrite(registo.matricula,6,1,stdout);
            printf("\n%s",registo.proprietario);
            printf("\n\n");
            getchar();
            i++;
        }
        
    }
    printf("Fim do ficheiro");
    fclose(fa);
    }
    
    void apagar_registo()
    {
    FILE *fa;
    veiculo_t registo;
    char mat[6];
    int g=0;
    char op;
    system("cls");
    fa=fopen("regist.bin","rb");
        if(fa==NULL)
    {
            printf("ERRO: O ficheiro nao existe");
            exit(0);
    }
        printf("Insira a matricula do automovel, referente ao registo que quer eliminar:\n ");
        scanf("%s",mat);
        getchar();
        while(fread(&registo,sizeof(veiculo_t),1,fa) != 0)
    {
        if(strcmp(registo.matricula,mat)== 0);
        {
            g=1;
        }
    }
            if(g==0)
            {
                printf("O registo não existe!!\n");
                getchar();
                fclose(fa);
                exit(0);
            }
            else
            {
                printf("\nConfirma eliminação (S/N)\n");
                scanf("%s",&op);
                
                    if(op!='S'||op!='s')
                    {
                        fclose(fa);
                        return;
                    }
                    
                    else
                {
    
                    registo.apagado=1;
                }
                fclose(fa);
                return;
    }
    
    }
     

    ---------------------------------------------------------------
     
    Última edição pelo moderador: 29 de Abril de 2009
  2. iznougud

    iznougud I quit My Job for Folding

    Isso nao é C#, é C.

    Tens de criar uma array global ListaVeiculos do tipo veiculo_t:

    Código:
    veiculo_t* ListaVeiculos;

    Tens de criar uma variavel que te guarde o nº de veiculos na lista:

    Código:
    int numVeiculos = 0;
    Quando o programa arranca tens de ler o ficheiro que tens e fazer malloc de pelo tamanho 1:

    Código:
    ListaVeiculos = (veiculo_t*)malloc(1, sizeof(veiculo_t)); 
    Sempre que inserires 1 veiculo a lista tens de fazer um realloc para criares espaço para o próximo:

    Código:
    ListaVeiculos[numVeiculos] = registo;
    ListaVeiculos = (veiculo_t*)realloc(ListaVeiculos, numVeiculos + 1); 
    numVeiculos++;
    
     
  3. S0ul

    S0ul Power Member

    E não te esqueças de libertar memória(free) senão te garanto que vais ter problemas, e terás de reiniciar o pc para voltares a trabalhar ou testar :).
     
  4. iznougud

    iznougud I quit My Job for Folding

    Pois, esqueci-me de referir esse "pequeno" pormenor :D
     
  5. Lbboy

    Lbboy Power Member

    Nao vou ter que retirar/apagar nada do programa anterior ?

    E que ele ja gravava os dados introduzidos pelo teclado po ficheiro sem usar mallocs e reallocs..

    Esta linha de código vou introduzi la na função inserir_registo ?

    Código:
    ListaVeiculos = (veiculo_t*)malloc(1, sizeof(veiculo_t));
     
  6. FASC

    FASC Power Member

    Mas tens de usar realloc para quê? Isso é talvez das piores coisinhas para se usar em C, devido à sua ineficiência... Que tal listas ligadas ou duplamente ligadas?

    Se esse enunciado que deste for de uma universidade, o mundo está perdido...
     
  7. Lbboy

    Lbboy Power Member

    Basicamente sao 3 trabalhos que vou ter que entregar num so..

    o 1º trabalho pediame que fizesse o que este codigo faz.. com varias condicionantes em que numa das alineas pedia para usar o realloc coisa que n cheguei a fazer

    o 2 trabalho pediame para pegar o que fiz no 1º trabalho mas agora usando ficheiros.. ja esta feito

    o 3 trabalho era fazer uma makefile pa ser usada no linux

    do tipo vou ter um funcoes.c funcoes.h main.c e vou ter que fazer a makefile

    ja ta feito o esboço

    a minha duvida e mesmo nos mallocs e reallocs.. n sei se e pa meter nas funcoes ou no main..

    ps: sou de engenharia electrotecnica e nao de informatica.. tenho bastantes dificulades na programação :( as cadeiras que tenho em atraso sao ambas de programaçao
     
  8. Lbboy

    Lbboy Power Member

    Enunciado do 1º trabalho

    Código:
    Introdução
    A revisão dos conceitos de alocação dinâmica de memória e sua utilização é importante
    para que o aluno mais à frente tenha uma maior facilidade em lidar com o mecanismo de
    memória partilhada.
    Exercício
    Pretende-se escrever um programa que permita armazenar em memória uma lista de
    registos de automóveis. Os dados a guardar para cada automóvel são a matrícula (vector
    de 6 caracteres) e o nome do proprietário (string).
    Cada registo deverá obedecer à seguinte estrutura:
    #define NAME_BUFFER_SIZE 80
    typedef struct {
    char matricula[6];
    char proprietario[NAME_BUFFER_SIZE];
    char apagado; //iniciar a 0. Diferente de zero significa apagado.
    } veiculo_t;
    Para uma revisão de utilização de estruturas e apontadores para estruturas, analise os
    exemplos apresentados no final do enunciado.
    1) Implemente as rotinas das questões 1.1 e 1.2 de forma que seja possível testar o
    seguinte programa exemplo:
    void main() {
    veiculo_t v1;
    ler_registo(&v1);
    imprimir_registo(&v1);
    }
    1.1 – Implemente uma função void ler_registo(veiculo_t *v) que solicite
    os dados ao utilizador (matrícula e nome do proprietário) e preencha a estrutura apontada
    por v com os dados obtidos do teclado.
    Notas:
    a) a função só lê um registo;
    b) no caso do campo matrícula, copie apenas os 6 caracteres iniciais do texto
    introduzido pelo utilizador para o respectivo campo da estrutura veiculo_t (utilize a
    função memcpy()).
    1.2 - Implemente uma função void imprimir_registo(veiculo_t *v) que
    imprima no ecrã os dados contidos na estrutura apontada por v.
    1.3 – Teste as rotinas desenvolvidas em 1.1 e 1.2 recorrendo ao programa apresentado
    acima.
    
    2) O programa principal deverá permitir a escolha das seguintes opções (utilize a
    instrução switch):
    1. Inserir registo. Deverá solicitar a introdução da matrícula e o nome do
    proprietário.
    2. Imprimir todos os registos no "standard output".
    3. Apagar registo.
    2.1 - Implemente o menu principal do programa e as opções 1 e 2. A lista deverá ser
    armazenada num bloco de memória alocado dinamicamente e cujo tamanho deverá
    crescer à medida que são inseridos registos (use a função realloc()).
    Nota: na opção 2, os registos cujo campo "apagado" tenha valor diferente de 0 não
    deverão ser impressos.
    2.2 - (Optativa) Implemente a opção de apagar registos, usando a técnica de eliminação
    "preguiçosa" (marcar registos apagados através do campo "apagado"). Deverá ser pedida
    a matrícula correspondente ao registo a eliminar (considere que não existem repetições de
    matrículas).
    Apêndice
    Considere as declarações abaixo:
    typedef struct {
    int i;
    char c;
    } mystruct_t;
    mystruct_t *ptr;
    Exemplo 1:
    ptr = malloc(sizeof(mystruct_t));
    (*ptr).i=1;
    ptr->i=1;
    ptr[0].i=1;
    //as 3 instruções anteriores são equivalentes
    Exemplo 2:
    ptr = malloc(NUMERO_DE_REGISTOS*sizeof(mystruct_t));
    ptr[0].i=1;
    ptr[0].c='a';
    ptr[1].i=2;
    ptr[1].c='b';
    ...
    printf("%d %c\n", ptr[0].i, ptr[0].c);
    
     
  9. FASC

    FASC Power Member

    Eu também sou de Electro, mas caramba, nunca me fizeram usar realloc, bem pelo contrário, era uma função bastante desaconselhada devido à sua ineficiência.

    Anyway, já que estás a usar linux, escreve "man realloc" e "man malloc" no terminal. Se tiveres as manpages instaladas deve aparecer-te a explicar as funções e exemplos.

    Qualquer das formas o básico é este:
    Quando se trabalha com dados dinâmicos, usa-se "malloc" ou "calloc" (a diferença é que o calloc limpa a memória alocada (escreve zeros): é útil para quando se quer que tudo esteja limpo, inútil se a seguir a alocares a memória preencheres todos os campos). Estas funções devolvem-te um apontador para o sítio da memória onde o espaço foi reservado (se não sabes trabalhar com apontadores, procura exemplos na net que é o que não falta), logo tens de guardar este apontador num "sítio": normalmente listas, no teu caso um array de dimensão variável. Este array terá obviamente ser do tipo *estrutura, onde "estrutura" é aquilo que estás a alocar previamente, e a variável que aponta para o array será do tipo **estrutura.

    Como o teu array tem de ser de dimensão variável para suportar o crescente de dados, tens de o (re)alocar sempre que adicionas ou retiras algo dele. Para o efeito (e semelhante ao malloc), existe o realloc que realoca para outra zona da memória um dado array de dados, de uma dimensão inicial para uma dimensão final, daí como já te foi dito, precisares de guardar o tamanho actual do array numa variável (incrementada quando adicionas ao array, decrementada quando retiras).
     

Partilhar esta Página