Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

insonias

Ler ficheiro Binário - C

Mensagens Recomendadas

insonias

Boas.

Eu sou novo por estas bandas e pelo o que pesquisei aqui nos tópicos não encontrei nada que me ajudasse.

O meu problema está em ler um ficheiro binário para carregar a info para memória. Ou seja, fazer um load da lista ligada a partir de um ficheiro binário.

Já tenho uma função que escreve num ficheiro a lista ligada (penso eu).


void gravarclientes(List l)
{
     FILE *f;
     f=fopen("clientes.dat","wb");
     while (l)
     {
         if(l->next!=NULL)
         {
            fwrite(l,sizeof(cliente), 1, f);
                        l=l->next;
         }
         else
         {
             l=l->next;
         }
     }
     fclose(f);
}

Agora não sei como reverter a situação, ou seja, tornar a colocar a info numa lista ligada.

Any1 help me?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

O problema que se levanta quando tu estás a ler de ficheiros para listas ligadas é aquele ponteiro que aponta para o próximo nó da lista.

Uma ideia é ires lendo e a cada nó que lês (tipicamente com a função fread) apontas aquele ponteiro para uma próxima leitura, ou seja, crias (dinamicamente) outra estrutura e na próxima leitura lês para o próximo nó (que já foi criado).

Só mais uma coisa, esse código, funciona? Não te dá Segmentation Fault? É que parece que estás a fazer um loop infinito e não tens condições de paragem pelo que vejo.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

O compilador não descarrila ... no entanto, quando abro o ficheiro o texto é o seguinte (sei que num ficheiro binário não é possível ler nada no entanto)

ÿÿÿÿX¡ CALAPPDATA=C:\Users\hp\AppData\Local LOG¡   1 ¡ ws\system32\cmd.exe ineS      X¡ X¡   2 ¡ ws\system32\cmd.exe X¡         X¡ ˜¡

será isto normal? ... uma vez que nunca vi um ficheiro deste tipo em binário

Localhost, podes dar um exemplo .. para ser sincero não domino lá muito esta matéria.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Tenta fazer o while assim:

while(l->next != NULL) {
  // código
}

edit: Visto que no último post tens literalmente o trabalho feito (o que é mau) tirei o código de exemplo.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yyajsayy

Acho que deve ser qualquer coisa assim que pretendes..


#define DIM 200

List *escreverclientes()
{
        FILE *file;
char buff[DIM];
char *c;
char *str;
List *lista=NULL;

//abrir ficheiro
file = fopen(Clientes.dat,"r");

        //verificar se abertura foi bem sucedida!
if(file == NULL)
{
	printf("erro");
	return 0;
}

      
        //ir até ao fim do ficheiro
while (!feof(file))
{
	//obter linha, envias para o char buff a string vinda do clientes.dat com tamanho DIM (200) do ficheiro
	c=fgets(buff,DIM,file);

                //aqui verificas se existem dados ainda ..
	if (c==NULL)
	{
		break;
	}

                //podia passar directamente com o c, mas vamos filtrar para verificar mesmo a string (linha-a-linha)	
                str = strtok(buff, "\n");
        
                        //verificar + 1 vez se ainda há dados
                        if (str == NULL)
	       {
		   exit(0);
                       }
        
        
        
       //enviar para a lista
       
       //se a lista estiver vazia vamos então fazer um nodo, e armazenar lá info
       if(lista==NULL) {
                       
                        //declaramos memoria para o nodo do tipo estrutura
                        lista=(List*)malloc(sizeof(List));
                        //copiamos os dados vindos do clientes.dat para o teu nodo, neste caso para um vector de caracters
                        strcpy(lista->dados,str); //dados e o teu char dados[200]; ou outro parâmetro qualquer
                        //aqui colocamos o teu apontador da lista a apontar para null, visto que não tem nenhum nodo para apontar
                        lista->next=NULL;   
               
                    
        }

        else {
     
               	  //vamos percorrer a lista até encontrar o ultimo nodo para poder inserir mais nodos ...
                   while(lista->next != NULL)lista=lista->next; 
                  // declaramos memoria para o novo nodo
                   lista->next=(List*) malloc (sizeof(List));
                  // fazemos a copia como em cima..
                   strcpy(lista->next->dados,st);
    
                   lista->next->next=NULL;
                  
         }         
        
        
  
    }

fclose(file);    
    
    
return(lista);
}


Não testei o código mas a filosofia é essa, se tiveres problemas avisa :D


"If it don't work the first time, rename it to version 1.0."

http://seguranca-informatica.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

yyajsayy, obrigado pela ajuda, no entanto o meu problema não está em escrever no ficheiro (penso eu) mas sim em ler do ficheiro.

Além disso, para clarificar List já é por si um ponteiro para a estrutura.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Visto que não entendeste muito bem o exemplo que o yyajsayy deixou vou-te deixar um pequeno exemplo que te pode ajudar:

while(existem_dados) {
  if(i == 0):
    p = novo_no();
    ler(p);
  else:
    p->next = novo_no();
    ler(p->next);
  i++;
}


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

Espero que tenham paciência porque vão precisar xD

eu vou tentar .. mas à coisas que não percebo no exemplo do yyajsayy

Já agora ... a função de escrever está bem ... uma vez que sem isso não vale a pena tentar por a leitura do ficheiro a dar  :bored:

Relembro que estou a querer ler/escrever num ficheiro em Binário !

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

A ideia que tens de ter sempre em mente é que ao leres tens de ir criando nós e lendo para esses mesmo nós.

Só uma pergunta, quando queres fazes a leitura a tua lista ligada já está criada? É que se tiver é muito mais fácil.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

A ideia que tens de ter sempre em mente é que ao leres tens de ir criando nós e lendo para esses mesmo nós.

Só uma pergunta, quando queres fazes a leitura a tua lista ligada já está criada? É que se tiver é muito mais fácil.

hm ... podes explicar melhor a parte de "a tua lista ligada já está criada?" ?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Antes de fazeres a leitura do ficheiro já existe em memória todas as estruturas ligadas umas às outras ou ainda tens de as criar para depois leres para elas?


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

Antes de fazeres a leitura do ficheiro já existe em memória todas as estruturas ligadas umas às outras ou ainda tens de as criar para depois leres para elas?

Hmm .. supostamente elas são criadas antes e depois dai o load & save da informação, para que na próxima utilização do programa possa alterar/criar/eleminar nós!

🤔

Comentei as linhas do excerto de código acima para uma melhor compreensão da tua parte, espero que ajude :(

sim .. isso ajuda a perceber .. no entanto tens aqui

c=fgets(buff,DIM,file);

buff? porquê DIM? só percebi o file =)

strcpy(lista->next->dados,st);
            lista->next->next=NULL;

não percebo nada disto  :D

Então tu tens de a cada leitura que fazes criar um novo nó. Já deixei há alguns posts atrás um pseudo código que te pode ajudar.

o código do yyajsayy não faz isso?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Então tu tens de a cada leitura que fazes criar um novo nó. Já deixei há alguns posts atrás um pseudo código que te pode ajudar.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yyajsayy

Dim é um define com o valor 200, pode-se substituir por um valor qualquer, atenção a tua string no file não pode exceder esse tamanho.

Sim, o código faz o que ele pretende é só copy paste, caso não funcione deve ser um pequeno retoque, não testei.

cumps


"If it don't work the first time, rename it to version 1.0."

http://seguranca-informatica.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

Dim é um define com o valor 200, pode-se substituir por um valor qualquer.

Sim, o código faz o que ele pretende é só copy paste.

cumps

que estupidez a minha ... claro que sabia o que era o DIM .. o que eu queria perguntar é o porquê daquele parâmetro e porquê 200 ?

Além disso .. podes explicar o seguinte:

strcpy(lista->next->dados,st);
    
                   lista->next->next=NULL;

Surgiu-me outra dúvida ... o return do teu programa dá o header da lista certo? Como é que eu associo esse return ao header, uma vez que, eu tenho uma função que cria um header, que é com o qual eu faço quase tudo no programa?!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Aquele código deve fazer parte de um projecto pessoal dele, como deves compreender as variáveis não têm o mesmo nome que as tuas. Mais uma vez, vê o código que te deixei e tenta aplicar.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

Surgiu-me outra dúvida ... o return do teu programa dá o header da lista certo? Como é que eu associo esse return ao header, uma vez que, eu tenho uma função que cria um header, que é com o qual eu faço quase tudo no programa?!

podem postar um exemplo do conteúdo de um ficheiro em binário?

é que eu não sei se o que eu vejo no meu é realmente alguma coisa escrita de interessante ...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yyajsayy

que estupidez a minha ... claro que sabia o que era o DIM .. o que eu queria perguntar é o porquê daquele parâmetro e porquê 200 ?

Além disso .. podes explicar o seguinte:

strcpy(lista->next->dados,st);
    
                   lista->next->next=NULL;

Surgiu-me outra dúvida ... o return do teu programa dá o header da lista certo? Como é que eu associo esse return ao header, uma vez que, eu tenho uma função que cria um header, que é com o qual eu faço quase tudo no programa?!

Isso é facil repara.

strcpy(lista->next->dados,str);

Aqui só estás a copiar para o novo nodo o valor capturado no file.

Lá em cima guardamos a string vinda do ficheiro na variável str, aqui só estamos a copiar para o vector da tua estrutura esse valor ..

Supostamente na tua typedef strut List{

char dados[200];

}

deves lá ter um parâmetro parecido ..

Aqui ..

lista->next->next=NULL;

Só estás a dizer que esse novo nodo criado está a apontar para vazio, ou seja não tens nenhum nodo criado visto que inseres os dados como em uma fila ...

Espero que percebas :D


"If it don't work the first time, rename it to version 1.0."

http://seguranca-informatica.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
yyajsayy

Não sei se vou responder à tua dúvida, mas ler do ficheiro será a tua primeira operação .. ou mesmo não sendo ..

Então sabes que essa função escreverClientes().. é do tipo de estrutura List*, sabes que ela devolve um apontador para a cabeça da lista ....

Então, no teu main () .. concerteza terás um apontador de estrutura, ou seja a tua lista ..

só tens de fazer algo do género ..

main() {

List *L;

L=escreverClientes();
}

visto que esta função é do teu tipo de estrutura e devolve um apontador..

Percebes?


"If it don't work the first time, rename it to version 1.0."

http://seguranca-informatica.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
insonias

Isso é facil repara.

strcpy(lista->next->dados,str);

Aqui só estás a copiar para o novo nodo o valor capturado no file.

Lá em cima guardamos a string vinda do ficheiro na variável str, aqui só estamos a copiar para o vector da tua estrutura esse valor ..

Supostamente na tua typedef strut List{

char dados[200];

}

deves lá ter um parâmetro parecido ..

tenho mais isto:

typedef struct clientes_list {
    int nib;
    char nome[10];
    char sobrenome[15];
    int contacto;
    int pin;
    int block;
    float saldo;
    struct clientes_list *next;
}cliente;

Aqui ..

lista->next->next=NULL;

Só estás a dizer que esse novo nodo criado está a apontar para vazio, ou seja não tens nenhum nodo criado visto que inseres os dados como em uma fila ...

Espero que percebas :D

não seria list->next = NULL ??

Não sei se vou responder à tua dúvida, mas ler do ficheiro será a tua primeira operação .. ou mesmo não sendo ..

Então sabes que essa função escreverClientes().. é do tipo de estrutura List*, sabes que ela devolve um apontador para a cabeça da lista ....

Então, no teu main () .. concerteza terás um apontador de estrutura, ou seja a tua lista ..

só tens de fazer algo do género ..

main() {

List *L;

L=escreverClientes();
}

visto que esta função é do teu tipo de estrutura e devolve um apontador..

Percebes?

Esta é a função que eu tenho para criar o header ...


List cria_header(void)
{
    List aux;
    aux = (List)malloc(sizeof(cliente));
    if(aux != NULL){
        aux->nib = -1;
        aux->next = NULL;
    }
    return aux;
}

no entanto ... caso eu não tenha nada ainda no ficheiro ... quando vou carregar a info o que é que vai aparecer no Header ?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.