Ir para conteúdo
Fórum Script Brasil
  • 0

Leitura e Escrita de arquivos


Loco

Pergunta

Confesso que não sei muito sobre leitura e escrita em arquivos

li uns tutoriais, cursos online e não consigo trabalhar com uma estrutura

Estou com problema na leitura/ escrita de estruturas em arquivos

Quero armazenar uma estrutura repetidas vezes em um txt

e depois carregar todos os dados num vetor de estruturas

ou seja

a estrutura contem

nome, idade e telefone

no txt deve ficar a estrutura toda salva (sei que muitas vezes não fica legivel mas isso não vem ao caso)

segue o codigo de teste que estou usando

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

FILE *arq;
struct pess{
       int idade;
       char nome[30];
       int telefone;
       }pessoa[3];
       
       
main(){arq=fopen("teste.txt", "w+");

pessoa[0].idade=20;
strcpy(pessoa[0].nome,"PESSOA 1");
pessoa[0].telefone=2300032;

pessoa[1].idade=26;
strcpy(pessoa[1].nome,"PESSOA 2");
pessoa[1].telefone=5522666;

pessoa[2].idade=70;
strcpy(pessoa[2].nome,"PESSOA 3");
pessoa[2].telefone=234634;

fwrite(&pessoa, sizeof(pess), 1, arq);

rewind(arq);
struct pess alguém[3];

fread(&alguém,sizeof(pess), 1,arq);
printf("\nalguem.idade %d\n", alguém[0].idade);
puts(alguém[0].nome);
printf("alguém.telefone %d\n\n", alguém[0].telefone);

printf("\nalguem.idade %d\n", alguém[1].idade);
puts(alguém[1].nome);
printf("alguém.telefone %d\n\n", alguém[1].telefone);

//fread(&alguém,sizeof(pess), 1,arq);
printf("\nalguem.idade %d\n", alguém[2].idade);
puts(alguém[2].nome);
printf("alguém.telefone %d\n\n", alguém[2].telefone);

system("pause");
}

Link para o comentário
Compartilhar em outros sites

4 respostass a esta questão

Posts Recomendados

  • 0

olá Loco,

O problema está na hora de informar o tamanho para gravação.

O sizeof de pess retorna o tamanho referente a pessoa[0], então os registros 1 e 2 não são gravados.

o correto seria: fwrite(&pessoa, sizeof(pess) * 3, 1, arq);

Assim os registros 0, 1 e 2 serão gravados no seu arquivo.

O mesmo deve ser observado na leitura, ou seja, usar fread(&alguém,sizeof(pess) * 3, 1,arq);

Claro que você pode ler um registro de cada vez com em um laço como:

for (int n = 0; n < 3; n++)

{

fread(&alguém,sizeof(pess), 1,arq);

printf("\nalguem.idade %d\n", alguém[n].idade);

puts(alguém[n].nome);

printf("alguém.telefone %d\n\n", alguém[n].telefone);

}

Mais uma coisa, você abriu o arquivo como texto ("w+") e está gravando em formato binário, isso pode dificultar um pouco a sua vida.

Se quer ler suas informações num editor de texto, como o notepad por exemplo, escreve no arquivo usando o fprintf.

Porem, se quer mesmo tratar o arquivo como binário, usa ("w+b").

Espero ter ajudado.

Abs

Link para o comentário
Compartilhar em outros sites

  • 0

Muito Obrigado CPP me ajudou muito!!

Corrigi oque você falou e deu certo

agora esta gravando e lendo.. era o w+b que eu não tinha feito ainda..

mas agora estou com outro problema

O usuário vai informar

Nome

idade

telefone

o programa deve deixar o usuario informar quantos telefones quiser

para isso vou usar ponteiro dentro da estrutura.. dando realloc no incremento.. td isso ta tranquilo

mas como puxar os dados devolta do arquivo pra poder ser editado no programa e depois gravar td no arquivo devolta

tipo

a primeira pessoa tem 1 tel

a segunda tem 20 tel

a terceira 10 telefones

como vou fazer para puxar dados de diferentes tamanhos, numa estrutura?

Fiz esse codigo pra mostrar o problema que tenho ao abrir os dados

esse codigo só cria o arquivo que será aberto no outro codigo

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

FILE *arq;

struct pess{
       int idade;
       char nome[30];
       int * telefone;
       int quantostel;
       }pessoa[3];
       
       
main(){arq=fopen("teste.txt", "w+b");

/*pessoa[0].idade=20;
strcpy(pessoa[0].nome,"PESSOA 1");
pessoa[0].telefone=(int *) malloc(sizeof(int)*3);
pessoa[0].telefone[0]=100000;
pessoa[0].telefone[1]=111111;
pessoa[0].telefone[2]=222222;
pessoa[0].quantostel=3;


pessoa[1].idade=26;
strcpy(pessoa[1].nome,"PESSOA 2");
pessoa[1].telefone=(int *) malloc(sizeof(int)*1);
pessoa[1].telefone[0]=999999;
pessoa[1].quantostel=1;


pessoa[2].idade=70;
strcpy(pessoa[2].nome,"PESSOA 3");
pessoa[2].telefone=(int *) malloc(sizeof(int)*1);
pessoa[2].telefone[0]=888888;
pessoa[2].quantostel=1;


fwrite(&pessoa, (sizeof(pess)*3), 1, arq);
fclose(arq);
}

Codigo do programa que abre o arquivo e puxa todos os dados para uma estrutura para que possa ser trabalhado

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

FILE *arq;

struct pess{

char nome[30];

int * telefone;

}pessoa[3];

main(){arq=fopen("teste.txt", "w+b");

struct pess alguém[3];

//Aloquei direto no tamanho que estava la no codigo de cima (Depois faço algo dinamico)

alguém[0].telefone=(int *) malloc(sizeof(int)*3);

alguém[1].telefone=(int *) malloc(sizeof(int)*1);

alguém[2].telefone=(int *) malloc(sizeof(int)*1);

//Carregando os dados do arquivo txt na estrutura alguém

fread(&alguém,(sizeof(pess)*3), 1,arq);

//Imprimindo os dados

puts(alguém[0].nome);

printf("alguém.telefone %d\n\n", alguém[0].telefone[0]);

printf("alguém.telefone %d\n\n", alguém[0].telefone[1]);

printf("alguém.telefone %d\n\n", alguém[0].telefone[2]);

puts(alguém[1].nome);

printf("alguém.telefone %d\n\n", alguém[1].telefone[0]);

printf("\nalguem.idade %d\n", alguém[2].idade);

puts(alguém[2].nome);

printf("alguém.telefone %d\n\n", alguém[2].telefone[0]);

system("pause");

}

Se ficou td muito confuso a atividade é o seguinte

Descrição da atividade:

Crie um sistema de agenda de contatos.

Para cada registro de pessoa deverão ser armazenados os seguintes atributos:

Nome;

Data de nascimento;

Uma lista de telefones;

Uma lista de e-mails;

O sistema deverá armazenar o registro das pessoas cadastradas em um arquivo.

O sistema deverá permitir a inclusão de novas pessoas na agenda.

O sistema deverá permitir a edição dos dados das pessoas já cadastradas.

O sistema deverá permitir a remoção de pessoas anteriormente cadastradas.

O nome não deverá ter limites de caracteres.

Ambas as listas, de telefone e e-mails não devem ter um número limitado, podendo ter inúmeros registros. (Esse está sendo o grande problema, trabalhar com arquivo e com numero ilimitado de emails e tels)

Link para o comentário
Compartilhar em outros sites

  • 0

Fala ai Loco,

Agora você complicou as coisas heim.

Mas, vamos lá.

Primeiro, você tem que entender e tomar cuidado quando usa sizeof() envolvendo ponteiros.

Por exemplo:

int numeroA;
int numeroB[10];
int *numeroC;

numeroC = (int)malloc(400);

(valores considerando compiladores que geram código para 32bits)
sizeof(numeroA); --> retorna o valor 4 
sizeof(numeroB); --> retorna o valor 40 (4 * 10)
sizeof(numeroC); --> retorna o valor 4 independente de ter feito malloc(400) porque sizeof(numeroC) retorna o tamanho de um ponteiro (4 bytes) e não da memória alocada.
Então seu fwrite(&pessoa, (sizeof(pess)*3), 1, arq); não funciona mais como você esperava. Além disso, se você gravar a estrutura não vai levar os dados alocados dinamicamente. Isso porque quando você usa &pessoa está informando a posição de memória onde sua estrutura foi alocada, mas, o malloc realizado para alocar espaço para os telefones estão numa posição de memória diferente. Resumindo, o fwrite vai gravar no arquivo o endereço apontado por telefone (ou seja, 4 bytes), mas não 'os numero de telefones informados'. Outra dica, quando você usa w+b você cria o arquivo, quero dizer, você apaga o conteudo dele, então, sua rotina de leitura deve usar r+b pra manter os dados gravados anteriormente e ainda permitir atualizações. Dá uma olhada nas funções: fopen(), fread(), fwrite(), fprintf(), fscanf(), fseek(), ftell() Fiz algumas modificações no seu código pra facilitar as explicações. Vê se tá fácil de entender. Se precisar pode falar. Abs
void main(void)
{
    FILE *arq;

    struct pess{
           int idade;
           char nome[30];
           int quantostel;
           int *telefone;
           }pessoa[3];
           
           
    arq=fopen("Agenda.bin", "w+b");

    pessoa[0].idade=20;
    strcpy(pessoa[0].nome,"PESSOA 1");
    pessoa[0].telefone=(int *) malloc(sizeof(int)*3);
    pessoa[0].telefone[0]=101;
    pessoa[0].telefone[1]=102;
    pessoa[0].telefone[2]=103;
    pessoa[0].quantostel=3;

    pessoa[1].idade=26;
    strcpy(pessoa[1].nome,"PESSOA 2");
    pessoa[1].telefone=(int *) malloc(sizeof(int)*1);
    pessoa[1].telefone[0]=201;
    pessoa[1].quantostel=1;

    pessoa[2].idade=70;
    strcpy(pessoa[2].nome,"PESSOA 3");
    pessoa[2].telefone=(int *) malloc(sizeof(int)*1);
    pessoa[2].telefone[0]=301;
    pessoa[2].quantostel=1;

    // grava um registro de cada vez
    for (int n = 0; n < 3; n++)
        {
        // grava a primeira parte da estrutura (idade, nome e qtd de telefones)
        fwrite(&pessoa[n], (sizeof(pess)-sizeof(int *)), 1, arq);
        // grava os telefones desse registro usando o ponteiro alocado e a quantidade de telefones informada
        fwrite(pessoa[n].telefone, sizeof(int) * pessoa[n].quantostel, 1, arq);
        }
    fclose(arq);
}
Programa que lê os dados e exibe na tela
void main(void)
{
    FILE *arq;

    struct pess
        {
        int idade;
        char nome[30];
        int quantostel;
        int *telefone;
        };

    arq=fopen("Agenda.bin", "r+b");

    struct pess alguém[3];

    //Carregando os dados do arquivo txt na estrutura alguém

    // le um registro por vez
    int t;
    for (int n = 0; n < 3; n++)
        {
        // le a primeira parte do registro (idade, nome e qtd de telefones)
        fread(&alguém[n],(sizeof(pess) - sizeof(int *)), 1,arq);
        // aloca a memoria necessaria para os registros de telefone desse cliente usando a quantidade de telefones lida do arquivo
        alguém[n].telefone = (int *)malloc(sizeof(int) * alguém[n].quantostel);
        // le os telefone do arquivo
        fread(alguém[n].telefone, sizeof(int) * alguém[n].quantostel, 1, arq);
        puts("--------------------------------------------------");
        printf("alguém.idade %d\n", alguém[n].idade);
        printf("alguém.quantostel %d\n", alguém[n].quantostel);
        puts(alguém[n].nome);
        for (t = 0; t < alguém[n].quantostel; t++)
            printf("alguém.telefone %d\n", alguém[n].telefone[t]);
        }
    fclose(arq);
        
    system("pause");
}

Editado por CPP
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...