Editar arquivo binario [AJUDA]

1. Editar arquivo binario [AJUDA]

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 12/01/2017 - 11:12h

Ola pessoal, estou com um problema no código que simula uma biblioteca em .bin, especificamente na opção 6 onde eu tenho que editar algo que ja foi cadastrado no arquivo Binario ja tentei algumas coisas e não funcionou.
Quem puder me ajudar agradeço desde já.

OBS: Estou aprendendo C recentemente se tiver algum erro me desculpe.

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

typedef struct {
char livro[50];
char prateleira[50];
float preco;

}biblioteca;



int main(){

int opc,a,b,c,d,ret=1;
char resp='s';
char busca[50];
biblioteca x;
float busc;
FILE *fp;

if(fp != NULL){

//while(resp == 's' || resp == 'S'){
do {

system("cls");
printf("==========MENU==========\n");
printf("1)Cadastrar.\n");
printf("2)Visualizar Biblioteca.\n");
printf("3)Buscar pelo Livro.\n");
printf("4)Buscar pela Prateleira.\n");
printf("5)Buscar pelo Preco.\n");
printf("6) Mudar preco do Livro");
printf("Escolha uma opcao: ");
scanf("%i",&opc);



if(opc==1){

printf("Livro: ");
fflush(stdin);
gets(x.livro);

printf("Prateleira (A- B - C): ");
fflush(stdin);
gets(x.prateleira);

printf("Preco do Livro: ");
fflush(stdin);
scanf("%f",&x.preco);

fp = fopen("atv.bin","a+");
fwrite(&x,sizeof(biblioteca),1,fp);
fclose(fp);

printf("\nDesejas continuar (s) ou (n)? ");
fflush(stdin);
scanf("%c",&resp);

}


else if(opc==2){

fp = fopen("atv.bin","a+");



if(fp != NULL){


while(ret==1){

ret = fread(&x,sizeof(biblioteca),1,fp);
if(ret==1){

printf(" Livro: %s\n Prateleira: %s\n Preco: R$%.2f\n\n=========================\n\n",x.livro,x.prateleira,x.preco);
}
}


fclose(fp);
fflush(stdin);
getchar();


}
}
else if(opc==3){
fp = fopen("atv.bin","a+");

printf("Digite o Livro: ");
fflush(stdin);
gets(busca);



while(ret==1){

ret = fread(&x,sizeof(biblioteca),1,fp);
if(ret==1){

if(ret == 1){

if(strcmp(busca,x.livro)==0){
printf("\n Prateleira: %s\n Preco: %.1f\n\n=========================\n\n",x.prateleira,x.preco);



}
}
}


}
fclose(fp);
fflush(stdin);
getchar();
}
else if(opc==4){



printf("Digite a Prateleira(A - B - C): ");
fflush(stdin);
gets(busca);

fp = fopen("atv.bin","a+");

while(ret==1){

ret = fread(&x,sizeof(biblioteca),1,fp);
if(ret==1){

if(ret == 1){

if(strcmp(busca,x.prateleira)==0){
printf("\n Livro: %s\n Preco: %.1f\n\n=========================\n\n",x.livro,x.preco);



}
}
}

}
fclose(fp);
fflush(stdin);
getchar();
}
else if(opc==5){


printf("Digite o Preco: ");
fflush(stdin);
scanf("%f",&busc);

fp = fopen("atv.bin","a+");

while(ret==1){

ret = fread(&x,sizeof(biblioteca),1,fp);
if(ret==1){

if(ret == 1){

if(busc==x.preco){
printf("\n Livro: %s\n Prateleira: %s\n\n\n=========================\n\n",x.livro,x.prateleira);




}
}
}

}


fclose(fp);
fflush(stdin);
getchar(); }

else if(opc==6 ) {



}


}while (opc);

}
return 0;
}



  


2. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 12/01/2017 - 17:42h

Boa Tarde.
Primeiramente vou te dar uma ideia diferente, tipo em vez de ficar acrescentando ao arquivo binário, utilize de vetores, será mais prático, existem ferramentas dinâmicas (vector,map,list) para isso, declaradas ([]).
Como você esta cadastrando mais de um livro isso se torna mais prático.
Criar o arquivo binário.

FILE *fp = fopen("lib.db","w+b");

Obs. Veja que utilizei o método como w+b, w+=(Criar, zerar e escrever),b=(Binário);

Escrever:

biblioteca x[10];
fwrite(&x,sizeof(x),sizeof(biblioteca),fp);

Obs. Veja que informei o tamanho da minha variável e também da minha estrutura.

Ler:

size_t filesize(const char * path) {
size_t size;
FILE *fp = fopen(path,"rb");
fseek(fp,0L,SEEK_END);
size = ftell(fp);
rewind(fp);
fclose(fp);
return size;
}
FILE * fp = fopen("lib.db","rb");
fread(&x, filesize("lib.db"),sizeof(biblioteca),fp);

Obs. Veja que criei um método com nome filesize, para pegar o tamanho do arquivo de base de dados e utilizei ele na função fread.

Pronto agora, é só interagir, assim ele esta escrevendo e lendo do arquivo de base de dados.
O resto é com você, qualquer duvida, posta ai.

Boa Sorte!
--
Bruno Thomaz


3. Re: Editar arquivo binario [AJUDA]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 13/01/2017 - 21:08h

O problema é o fato de você estar usando modo "a+" para abrir o arquivo. Esse modo implica que todas as operações de escrita serão realizadas no final do arquivo, mesmo que você tente reposicionar o ponteiro de gravação.

A melhor maneira de abrir um arquivo cujo conteúdo preexistente você queira modificar é fazendo o seguinte.

FILE *fp;
if(
/* Primeiro supõe que arquivo já existe, e tentar abrir para leitura + modificações ("r+"). */
(fp=fopen("nome_arquivo", "r+b"))==NULL
&& /* Se falhar (i.e. fp==NULL) ... */
/* ... tenta criar um arquivo novo, permitindo também leituras ("w+"). */
(fp=fopen("nome_arquivo", "w+b"))==NULL
){
/* Não conseguiu nem abrir nem criar. Logo, sinaliza erro e aborta.
fprintf(stderr, "Erro ao abrir/criar arquivo: %s.\n", strerror(errno));
exit(1);
}
/* Se chegar a este ponto, fp aponta para uma estrutura de arquivo válida. */



4. RE:

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 14/01/2017 - 11:10h

Muito obrigado aos 2 usuarios que ajudaram, arrumei o código e estou usando melhor os modos de abertura como r, r+,w,a+ e etc.
Mesmo com as ajudas ainda estou com duvida de como modificar um dado já cadastrado dentro do arquivo binario.


5. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 14/01/2017 - 11:31h

Bom dia,
Como o método que informei, você pode fazer isso.
Com o fread do modo que informei acima, você carrega todo conteúdo do arquivo na memória.
Podendo realizar todas as modificações necessárias.
Depois fwrite reescreva o novo conteúdo no arquivo binário.
Funcionalidade w+b, apaga o conteúdo do arquivo, sendo assim possível escrever tudo novamente.

Boa Sorte!
--
Bruno Thomaz


6. Resposta

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 14/01/2017 - 11:39h

Ok, irei rever oq vc colocou la encima e tentar, logo posto os resultados


7. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 14/01/2017 - 11:54h

Exemplo prático.

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

size_t filesize( const char * path ) {
size_t size=0;
FILE *fp = fopen(path,"rb");
if(fp != NULL) {
fseek(fp, 0L, SEEK_END);
size = ftell(fp);
rewind(fp);
fclose(fp);
}
//free(fp);
return size;
}

typedef struct {
int id;
} data;

int main() {
data d[3];
FILE *fp;
d[0].id = 1;
if((fp = fopen("teste.bin","w+b"))!=NULL) {
fwrite(&d,sizeof(d),sizeof(data),fp);
fclose(fp);
if((fp = fopen("teste.bin","rb"))!=NULL) {
fread(&d,filesize("teste.bin"),sizeof(data),fp);
printf("Leitura 1: %d\n",d[0].id);
//Modificando o valor de d[0].id
d[0].id =2;
if((fp = fopen("teste.bin","w+b"))!=NULL) {
fwrite(&d,sizeof(d),sizeof(data),fp);
fclose(fp);
}
if((fp = fopen("teste.bin","rb"))!=NULL) {
fread(&d,filesize("teste.bin"),sizeof(data),fp);
printf("Leitura 2: %d\n",d[0].id);
}
}

} else
exit(0);
return 0;
}

Resultado:

Leitura 1: 1 // Valor Inicial
Leitura 2: 2 // Valor Modificado

Boa Sorte!
--
Bruno Thomaz


8. Re: Editar arquivo binario [AJUDA]

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 15/01/2017 - 09:44h

SarusKant escreveu:

Exemplo prático.

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

size_t filesize( const char * path ) {
size_t size=0;
FILE *fp = fopen(path,"rb");
if(fp != NULL) {
fseek(fp, 0L, SEEK_END);
size = ftell(fp);
rewind(fp);
fclose(fp);
}
//free(fp);
return size;
}

typedef struct {
int id;
} data;

int main() {
data d[3];
FILE *fp;
d[0].id = 1;
if((fp = fopen("teste.bin","w+b"))!=NULL) {
fwrite(&d,sizeof(d),sizeof(data),fp);
fclose(fp);
if((fp = fopen("teste.bin","rb"))!=NULL) {
fread(&d,filesize("teste.bin"),sizeof(data),fp);
printf("Leitura 1: %d\n",d[0].id);
//Modificando o valor de d[0].id
d[0].id =2;
if((fp = fopen("teste.bin","w+b"))!=NULL) {
fwrite(&d,sizeof(d),sizeof(data),fp);
fclose(fp);
}
if((fp = fopen("teste.bin","rb"))!=NULL) {
fread(&d,filesize("teste.bin"),sizeof(data),fp);
printf("Leitura 2: %d\n",d[0].id);
}
}

} else
exit(0);
return 0;
}

Resultado:

Leitura 1: 1 // Valor Inicial
Leitura 2: 2 // Valor Modificado

Boa Sorte!
--
Bruno Thomaz


Mesmo sendo um exemplo prático como você citou, fiquei com algumas duvidas em relação ao código, ele carrega o conteudo do arquivo .bin na memória para poder realizar "modificações" e reescrever encima, entretanto ele vai reescrever encima dos outros livros que nao foram modificados mesmo querendo modificar apenas 1 livro entre 10 por exemplo. Se puder me explicar um pouco melhor o código agradeço




9. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 15/01/2017 - 11:15h

Exatamente, no momento que abrir o arquivo para escrita ele será zerado sobrescrevendo o conteúdo antigo.
Com binário não ha como escrever em pontos específicos, a estrutura pode variar de tamanho conforme a edição feita.
Não se preocupe, o desempenho é rapido, quase não da diferença.

Boa Sorte.
--
Bruno Thomaz


10. RE:

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 16/01/2017 - 04:00h

SarusKant escreveu:

Exatamente, no momento que abrir o arquivo para escrita ele será zerado sobrescrevendo o conteúdo antigo.
Com binário não ha como escrever em pontos específicos, a estrutura pode variar de tamanho conforme a edição feita.
Não se preocupe, o desempenho é rapido, quase não da diferença.

Boa Sorte.
--
Bruno Thomaz


Obrigado, consegui usar a opção de modificar com SEEK e uma variavel de posição para reescrever encima.
Agora estou tentando fazer algo parecido para a opção de REMOVER um arquivo desejado pelo usuario.
Eu pensei na opção de usar um .bin auxiliar para copiar as informações deletar o original e depois renomear o auxiliar. Sabe me dizer se funciona assim ou tem uma logica mais facil?



11. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 16/01/2017 - 08:59h

Cara, remover e alterar um arquivo binário, não tem como ter uma funcionalidade correta utilizando SEEK, devido os valores conterem tamanhos diferentes, suponhamos que a variável dentro da tua estrutura for um char * na primeira vez que escrever o conteúdo dela no arquivo ela teria tamanho de 30bytes, após editado teria 40bytes. Quando escrevesse ela iria sobrescrever algo mais no arquivo, gerando inconsistência.
Único modo de operar essa situação é se definir tamanhos específicos para cada campo da sua estrutura, gerando um arquivo bem maior que o necessário.
--
Bruno Thomaz


12. Re: Editar arquivo binario [AJUDA]

Joao Oliveira
raizoku

(usa Ubuntu)

Enviado em 16/01/2017 - 11:37h

SarusKant escreveu:

Cara, remover e alterar um arquivo binário, não tem como ter uma funcionalidade correta utilizando SEEK, devido os valores conterem tamanhos diferentes, suponhamos que a variável dentro da tua estrutura for um char * na primeira vez que escrever o conteúdo dela no arquivo ela teria tamanho de 30bytes, após editado teria 40bytes. Quando escrevesse ela iria sobrescrever algo mais no arquivo, gerando inconsistência.
Único modo de operar essa situação é se definir tamanhos específicos para cada campo da sua estrutura, gerando um arquivo bem maior que o necessário.
--
Bruno Thomaz


Eu estava tentando algo como esse code
char exusuario[50];


printf("Digite o Nome do Usuario: ");
fflush(stdin);
gets(exusuario); // PEDE O USUARIO

fp = fopen("testzao.bin", "r");

while(fread(&x, sizeof(menu), 1, fp)==1){

if(strcmp(exusuario,x.usuario)==0){ // VERIFICA E BUSCA O USUARIO /INFORMA OS DADOS DELE
printf("\nUsuario: %s",x.usuario);
printf("\nSenha: %i",x.senha);
printf("\nEmail: %s", x.email);

printf("\n\nDigite (1) para excluir: ");
scanf("%d", &op);
fflush(stdin);
switch(op) {
case 1:
fp = fopen("auxiliar.bin", "w+"); // ABRE / CRIA UM ARQUIVO AUXILIAR
if (fp == NULL){

printf("\n\nFalha na Abertura do Arquivo: auxiliar.bin");
}
else{
rewind(fp); //Posiciona o apontador de arquivo no byte 0 (início)
fread(&x, sizeof(menu), 1, fp);
while (! feof(fp))
{
if (x.usuario != usuario)
{
fwrite(&x, sizeof(menu), 1, fp);
}
fread(&x, sizeof(menu), 1, fp);
}
//Apaga o arquivo original e renomeia o auxiliar com o nome do original.
fclose(fp);
fclose(fp);
system("del testzao.bin");
system("ren auxiliar.bin testzao.bin");
}

break;

}
}
}
}




01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts