• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

so_simple

[Resolvido] structs e ficheiros

11 mensagens neste tópico

Alguem me arranja um tutorial ou me explica como se escreve e le structs em ficheiros binarios?!?!? preciso de ajuda urgente.....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bom.. penso que pretendes mais ou menos isto:

(em anexo envio um exercício inacabado que comecei a fazer há uns tempos e que nunca mais peguei.não tenho nada melhor em casa :x)

Imaginando que tens uma estrutura qualquer "reg" :

Para começar podes abrir um ficheiro com diferentes modos, eis uns exemplos: 

"w+" -> abre o ficheiro para reescrita, criando o ficheiro caso não exista ou eliminando o conteudo do ficheiro caso já exista.

"r"    -> abre o ficheiro para leitura

"r+"  -> abre o ficheiro para leitura e escrita (útil para alterar registos)

"a+" -> abre o ficheiro para escrita no final do ficheiro (é um append)

Primeiro tens de definir o apontador com o qual vais aceder ao ficheiro

FILE *f; // por exemplo

Depois tens de abrir o ficheiro com fopen, sintaxe:

f = fopen(path_do_ficheiro, modo);

exemplo: f = fopen("c:\\ficheiro.dat","a+");

fopen devolve NULL caso o ficheiro não exista.

Uma coisa que podes fazer antes de usar um ficheiro é verificar se ele existe, exemplo:

if (fopen("c:\\lixo.dat","r")==NULL)

{

f=fopen("c:\\lixo.dat","w+"); // cria o ficheiro

fclose(f);                                // fecha o ficheiro

}

É boa prática que quando deixas de usar um ficheiro, o "feches" com o fclose(apontador);

Para leres um registo usas o fread( endereço_estrutura, sizeof(estrutura), numero_de_registos_a_ler, apontador_ficheiro);  (só costumo ler 1registo de cada vez)

exemplo:    fread(®, sizeof(reg), 1, f );

Para escrever um registo usas o fwrite, a sintaxe é igual -  fwrite( endereço_estrutura, sizeof(estrutura), numero_de_registos_a_ler, apontador_ficheiro); 

exemplo:    fwrite(®, sizeof(reg), 1, f );

Penso que só falta uma função importante para exercícios iniciais - o fseek. Nos ficheiros definidos com uma estrutura podemos aceder a uma posição directamente, ao contrário dos ficheiros sequenciais (de texto).

Por exemplo, se quiseres alterar um registo, podes fazer simplesmente uma escrita por cima do registo a alterar.

fseek(apontador_ficheiro, nbytes_q_pretendemos_avançar, posicao  (posicao: 0 - desde o inicio , 1 - desde a posicao actual do apontador, 2 - a partir do fim)

Caso o  nbytes seja negativo, o apontador volta atrás.

Exemplo:  fseek ( f , -1 * sizeof(reg) , 1); // volta uma posição atrás

                fseek ( f , n * sizeof(reg) , 1);  // avança n posições no ficheiro

                fseek ( f , 0, 0 );    // volta ao inicio do ficheiro

Espero ter ajudado, qualquer coisa diz  :)

Edit:  Obrigado Brinkaero, tinha-me esquecido dessa  :confused:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só para completar a informação dada pelo mogers

Para abrires um ficheiro de modo binário, acrescentas a letra b no modo como abres o ficheiro.

Por exemplo:

- Querias abrir  um ficheiro para leitura e escrita em modo binário, ficaria assim

    f = fopen("Exemplo.txt", "r+b");

Lembrar que as funções fread e fwrite devolvem os itens lidos e escritos com sucess,o respectivamente.

Atenção: Não devolve o n.º de bytes, mas sim o número de itens (int, char, struct,...)

E outra função útil que é  int feof(FILE *fich);

Esta função devolve true quando detecta o final do ficheiro.

Por exemplo para uma operação no ficheiro até à última posição seria:

  while (!feof(fp))
   {
           // operacao sobre o ficheiro
    }

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Juntei essa informação toda num artigo e metam num tópico novo. Já temos um tutorial de ficheiros em C++. Agora temos também de C.  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para abrires um ficheiro de modo leitura acrescentas a letra b no modo como abres o ficheiro.

Não querias dizer "em modo binário"?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para abrires um ficheiro de modo leitura acrescentas a letra b no modo como abres o ficheiro.

Não querias dizer "em modo binário"?

Erro meu, já está corrigido!  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porgrama meu para ler uma lista de um arquivo

Lista Atual;

FILE *Pe

while(fread(&Atual, sizeof(Livro),1,Pe)

InserirFinalLista(Pedidos,Atual); //Funcao para inserir no final da lista...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

void consulta_tudo()
{
int contador=1,i;
CONTA *p;
FILE *fc;
system("CLS");
fc=fopen("conta.DAT","r");
p=(CONTA *)malloc(sizeof(CONTA));

while(!feof(fc))
{
fseek(fc,contador*sizeof(CONTA),0);
fread(&p[contador-1],sizeof(CONTA),1,fc);
contador++;
}
for (i=0;i<contador;i++)
{
mostra_struct(p[i],2,0);
}
fclose(fc);
free(p);
printf("\nQualquer tecla para continuar...\n");
getch();
}

Obrigado pela ajuda...

Agora tenho o seguinte problema.. Isto é um funçao que vai copiar todos os registos para um array da struct CONTA mas n estou a conseguir mostrar o array....só csg mostrar 1 elemento por exemplo p[1] ou p[2]

a seguir ta o codigo da funcao para mostrar as structs

void mostra_struct(CONTA m, int orientacao, int clrscr)
{
int i=0;
if (clrscr==1)
{
system("CLS");
}

if (orientacao==1){
        printf("Data      : %d - %d - %d\n", m.data.dia, m.data.mes, m.data.ano);
        printf("Descricao :\n");/*falta descricao*/
        printf("Modo      : %s\n", m.tipo);
        printf("Valor     : %f\n", m.valor);
}
if (orientacao==2)
{
        printf("%d-%d-%d \t\t %s \t %f\n", m.data.dia, m.data.mes, m.data.ano, m.tipo, m.valor); 
}
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas

Tens um problema pk só estás a alocar espaço para um registo. Senão sabes o tamanho máximo de registos no ficheiro, a solução é ir realocando memória para o teu array. Eu não disse, pensei que soubesses, ao fazer fread ou fwrite o nosso apontador de ficheiro é automaticamente colocado na próxima posição, ou seja, não é necessário colocarmos um fseek.

Outra coisa, eu não sei explicar bem porquê, mas usando  while(!feof(fc))  a ultima posição do ficheiro é lixo e devemos ignorar este lixo. Não sei ao certo como funciona o feof para verificar o final do ficheiro.

Sendo assim, propunha-te o seguinte código:

void consulta_tudo()
{
    int contador=1,i;
    CONTA *p;    
    FILE *fc;
    system("CLS");
    fc=fopen("conta.DAT","r");
    p=(CONTA *)malloc(sizeof(CONTA));
    fread(&p[contador-1],sizeof(CONTA),1,fc);         
    while(!feof(fc))
    {        
        contador++;
        realloc(p,contador*sizeof(CONTA));              // adiciona a memoria necessaria para mais um registo. o realloc redefine o espaço de memoria                               
        fread(&p[contador-1],sizeof(CONTA),1,fc); // usado.. incrementando o contador e multiplicando pelo sizeof temos o espaço k precisamos.       
    }
    contador--; // subtrair o lixo
    fclose(fc);    
    for (i=0;i<contador;i++)    
         mostra_struct(p[i],2,0);
}

eu experimentei e funcionou (a outra funcao mantem-se igual)  ... cumps

0

Partilhar esta mensagem


Link 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