Editar arquivo binario [AJUDA]

13. Re: Editar arquivo binario [AJUDA]

Bruno Thomaz
SarusKant

(usa CentOS)

Enviado em 16/01/2017 - 16:18h

Boa tarde,
Cara você esta complicando o que é simples.
Segue um exemplo, de como se faz edição em arquivo binário.


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

typedef struct {
int id;
char * login;
char * senha;
} database;

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);
}
return size;
}

int main() {

database db[10];
database temp;
FILE * fp;
int i;

puts ("Iniciando\n");

puts ("Criar estrutura da base de dados.\n");
//Criar estrutura da base de dados.
for(i=0; i<sizeof(db)/sizeof(database); i++) {
db[i].id=0;
db[i].login = (char*) malloc(sizeof(char) * 30 +1);
db[i].senha = (char*) malloc(sizeof(char) * 30 +1);
}

puts("Criar Usuário\n");
//Criar usuário
temp.id = 1;
temp.login = (char*) malloc(sizeof(char) * 30 +1);
strcpy(temp.login,(char*)"TesteLogin");
temp.senha = (char*) malloc(sizeof(char) * 30 +1);
strcpy(temp.senha,(char*)"testesenha");
db[0] = temp;

puts("Guardar na base de dados db.bin\n");
//Guardar na base de dados db.bin
fp = fopen("db.bin","w+b");
fwrite(&db,sizeof(&db),sizeof(database),fp);
fclose(fp);

puts("Resetando a Estrutura\n");
//Resetando a Estrutura
//memset(&db,0,sizeof(db));

puts("Carregar conteúdo da base de dados.\n");
//Carregar conteúdo da base de dados.
fp = fopen("db.bin","rb");
fread(&db,filesize("db.bin"),sizeof(database),fp);
fclose(fp);

puts("Listar conteudo da base de dados.\n");
//Listar conteudo da base de dados.
for(i=0; i<sizeof(db)/sizeof(database); i++) {
printf("Id do Usuário: %d, Login: %s, Senha: %s\n",db[i].id,db[i].login,db[i].senha);
}

puts("\nProcurar pelo login TesteLogin e trocar a senha.\n");
//Procurar pelo login TesteLogin e trocar a senha;
for(i=0; i<sizeof(db)/sizeof(database); i++) {
if(strcmp(db[i].login,(char*)"TesteLogin")==0) {
strcpy(db[i].senha,(char*)"SenhaTrocada");
}
}

puts("Guardar na base de dados db.bin\n");
//Guardar na base de dados db.bin
fp = fopen("db.bin","w+b");
fwrite(&db,sizeof(&db),sizeof(database),fp);
fclose(fp);

puts("Carregar conteúdo da base de dados.\n");
//Carregar conteúdo da base de dados.
fp = fopen("db.bin","rb");
fread(&db,filesize("db.bin"),sizeof(database),fp);
fclose(fp);

puts("Listar conteudo da base de dados.\n");
//Listar conteudo da base de dados.
for(i=0; i<sizeof(db)/sizeof(database); i++) {
printf("Id do Usuário: %d, Login: %s, Senha: %s\n",db[i].id,db[i].login,db[i].senha);
}

return 0;
}


Compile o código e teste.
Vai ver como é simples.

Att
--
Bruno Thomaz


  


14. Re: Editar arquivo binario [AJUDA]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 18/01/2017 - 08:03h

Não querendo fazer nenhum ataque ou perseguição pessoal, o fato é que praticamente todas as sugestões e comentários do Bruno Thomaz ao longo deste tópico são ruins, e devem, pelo bem da sanidade, ser desconsiderados.

Alguns exemplos de coisas erradas ditas por ele, e a explicação de por que são erradas:

- Sugestão de trazer o arquivo inteiro para a memória: é algo que funciona bem somente quando o tamanho do arquivo é menor do que eventuais limites de memória impostos ao programa. Contudo, é temerário supor que esse seja o caso. Como ter certeza de que o arquivo não possui milhões de registros, ou que o programa não executa com severo limites de memória?

- O próprio exemplo de como implementar a solução proposta acima está errado. Ao declarar x como um vetor, a forma certa de gravar todos os elementos de x de uma só vez NÃO É com fwrite(&x, sizeof x, sizeof(tipo_de_x), fp), até porque há diversos erros internos nessa simples linha. Primeiro que o endereço de um vetor é dado pelo próprio nome do vetor, sem necessidade do operador &. Além disso, o segundo e o terceiro argumentos de fwrite() deveriam indicar, respectivamente, o tamanho de cada registro (em bytes) e a quantidade de registros adjacentes a ser gravada (multiplicando-se uma pela outra, obtém-se a quantidade total de bytes a ser manipulada), mas o exemplo dado já utilizou o tamanho total do vetor como segundo argumento, e ainda colocou o tamanho de cada registro como terceiro argumento, o que vai gerar um tamanho total a ser manipulado que é absurdo. A maneira correta de implementar a gravação de um vetor inteiro seria a seguinte: fwrite(x, sizeof x[0], sizeof x/sizeof x[0], fp).

- O exemplo de uso de fread() padece do mesmo mal, com valores disparatados como segundo e terceiro argumentos da função.

- Não faz o menor sentido falar que “[c]om binário não ha como escrever em pontos específicos” ou que “a estrutura pode variar de tamanho conforme a edição feita”. Também a crítica ao uso de fseek(), além de mal expressa, está totalmente equivocada.

- Além do problema com possíveis limites de memória, a abordagem de reescrever o arquivo inteiro tem outros problemas. (1) A partir de um certo tamanho, não muito grande, reescrever múltiplos registros num arquivo recriado se torna menos eficiente do que reescrever um único registro numa posição determinada de um arquivo preexistente. (2) Se ocorrer uma falha, como uma falta de energia, durante a gravação de uma quantidade grande de registros, o potencial para perda significativa de dados é muito maior do que o que tipicamente ocorreria com a (re)gravação de apenas um registro.



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts