usar realloc e malloc em C#

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:
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++;
 
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 :).
 
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));
 
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...
 
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
 
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);
 
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

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).
 
Back
Topo