Skip to content

Instantly share code, notes, and snippets.

@crissilvaeng
Last active September 14, 2020 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crissilvaeng/bae2d110ac26efbed43a to your computer and use it in GitHub Desktop.
Save crissilvaeng/bae2d110ac26efbed43a to your computer and use it in GitHub Desktop.
Código genérico para exemplificar consulta de arquivos binários.
/* GuiaArquivo.c
*
* Código genérico para exemplificar consulta de arquivos binários.
*
* GNU General Public License
* Copyright 2014 Cristina Silva <cristina@openmailbox.org>
*/
// Biblioteca básica para as funções de entrada e saida em C.
#include <stdio.h>
// Biblioteca para utilização de tipo booleano (true/false) em C.
// Consulta: http://devdocs.io/cpp/header/cstdbool
#include <stdbool.h>
// Biblioteca necessaria para função toupper.
#include <ctype.h>
// Biblioteca necessaria para sunção strcpy
#include <string.h>
// Definição de FALHA_ABERTURA para NULL. Apenas para facilitar a leitura.
// Consulta: http://devdocs.io/c/preprocessor/replace
#define FALHA_ABERTURA NULL
// Estrutura de registros no arquivo.
// Consulta: http://devdocs.io/c/language/struct
typedef struct
{
// Estrutura podem aceitar como campos tipos primitivos.
int subcampo01;
int subcampo02;
int subcampo03;
} tp_subestrutura; // Nome para nosso proprio tipo definido.
// Consulta: http://devdocs.io/c/language/typedef
// Um arquivo fonte pode ter zero, uma ou muitas estrturas.
typedef struct
{
int campo01;
char campo02[16];
float campo03;
// O tipo booleano ode ser substituido por um inteiro.
// Onde 0 assume o valor de falso e um assume o valor de verdadeiro.
bool campo04;
// Ou tipos definidos pelo programador. Como outra estrutura.
// Podem até mesmo ser utilizados dentro de outra estrutura.
// Porém esse tipo deve ser definido antes de ser utilizado.
tp_subestrutura campo05;
} tp_estrutura;
/* Exibe Dado : Forma generica.
* Uma função generica para exibição de dado.
* Parametro: A estrutura.
* Retorno: Nenhum.
*/
void exibeDados( tp_estrutura estrutura )
{
const char template_estrutura[256] = "\
Campo01 - inteiro: %d\n\
Campo02 - string: %s\n\
Campo03 - float: %f\n\
Campo04 - booleano: %d\n\
Campo05:\n\
Subcampo01: %d\n\
Subcampo02: %d\n\
Subcampo03: %d\n";
printf( template_estrutura, estrutura.campo01, estrutura.campo02, estrutura.campo03, estrutura.campo04,
estrutura.campo05.subcampo01, estrutura.campo05.subcampo02, estrutura.campo05.subcampo03);
}
/* Função de Conversão para Maiuscula : Forma Generica
* Parametro: Uma string.
* Retorno: String em Maiuscula.
*/
char* converteParaMaiuscula( char* string )
{
int contador = 0;
// A função strlen retorna o tamanho de uma string.
// Consulta: http://devdocs.io/c/string/byte/strlen
for( contador = 0; contador <= strlen( string ); contador++ )
{
// A função toupper retorna a maiuscula da letra informada.
// Consulta: http://devdocs.io/c/string/byte/toupper
string[ contador ] = toupper( string[ contador ] );
}
return string;
}
/* Gravação de Dados: Forma 01
* Nesta forma a leitura e gravação dos dados é feito dentro de uma única função.
* Parametros: O ponteiro do arquivo.
* Retorno: Nenhum.
*/
void gravaDados_forma01(FILE* arquivoParametro)
{
// É criada uma estrutura para armazenar os dados.
tp_estrutura estrutura;
// É feita a leitura dos campos:
scanf("%d", &estrutura.campo01);
scanf(" %[^\n]s", estrutura.campo02); // O %[^\n]s permite a lietura de strings com espaço.
scanf("%f", &estrutura.campo03);
int temporaria; // Necessario pois C não tem scanf para boolean.
scanf("%d", &temporaria);
estrutura.campo04 = temporaria;
// Para leitura de mais de uma hierarquia de membros utilizamos o . (ponto).
scanf("%d %d %d", &estrutura.campo05.subcampo01, &estrutura.campo05.subcampo02, &estrutura.campo05.subcampo03);
exibeDados( estrutura );
//O comando fwrite precisa de quatro parametros:
// 1. A referencia da estrutura onde estão os dados.
// 2. O tamanho da estrutura, para tal utilizamos a função sizeof:
// Consulta: http://devdocs.io/c/language/sizeof
// 3. O número de registros que serão gravados, ou seja, se nossa estrutura fosse um array:
// tp_estrutura estrutura[2];
// Deveria ser passado a função fwrite o tamanho do vetor, isso pode acontecer de duas formas:
// fwrite( &estrutura, sizerof(estrutura), 2, arquivoParametro); ou
// fwrite( &estrutura, sizerof(estrutura), strlen(estrturas), arquivoParametro);
// Consulta: http://devdocs.io/c/string/byte/strlen
// 4. O ponteiro para o arquivo onde sera feita a gravação.
// Consulta: http://devdocs.io/c/io/fwrite
fwrite( &estrutura, sizeof(estrutura), 1, arquivoParametro);
}
/* Leitura de Dados: Forma 02
* Esta função le os dados e retorna uma estrutura com todos eles.
* Parametros: Nenhum.
* Retorno: uma estrutura com os dados a serem gravados.
*/
tp_estrutura leDados_forma02()
{
// É criada uma estrutura para armazenar os dados.
tp_estrutura estrutura;
// É feita a leitura dos campos:
scanf("%d", &estrutura.campo01);
scanf(" %[^\n]s", estrutura.campo02); // O %[^\n]s permite a lietura de strings com espaço.
// A conversão de uma string para maiuscula pode ser interessante na hora de facilitar a consulta por string.
strcpy( estrutura.campo02, converteParaMaiuscula( estrutura.campo02 ) );
scanf("%f", &estrutura.campo03);
int temporaria; // Necessario pois C não tem scanf para boolean.
scanf("%d", &temporaria);
estrutura.campo04 = temporaria;
// Para leitura de mais de uma hierarquia de membros utilizamos o . (ponto).
scanf("%d %d %d", &estrutura.campo05.subcampo01, &estrutura.campo05.subcampo02, &estrutura.campo05.subcampo03);
}
main()
{
// É criado um ponteiro para o arquivo.
FILE* arquivo;
// Uma string para o nome do arquivo e o modo de abertura.
// Estes campos podem ser passados diretamente na função de abertura
// do arquivo, sem a necessidade de declarar variaveis para tal.
char nomeArquivo[16] = "arquivo.dat"; // Extensão .dat são comuns para arquivos bintarios.
char modoAbertura[4] = "a+b"; // Padrão de Mode de Abertura. xy ou x+y
// Consulta: Luis Damas - Linguagem C - Págiuna 232 e 233.
// O ponteiro para o arquivo recebe o retorno da função de abertura.
// Consulta: http://devdocs.io/c/io/fopen
arquivo = fopen( nomeArquivo, modoAbertura );
// Se o retorno da função fopen, agora no ponteiro arquivo, for igual a NULL ocorreu algum erro na abertura.
// Antes de realizar qualquer operação com arquivo, deve-se testar essa condição.
if ( !arquivo == FALHA_ABERTURA ) // Igual a dizer ( arquivo != FALHA_ABERTURA )
{
// Existem varias estratégias para fazer a gravação de um dado em um arquivo binario.
// Desde a mais simples, como uma função única:
gravaDados_forma01(arquivo);
// Até uma mais elaborada:
// Este if testa o retorno da função gravaDados_forma02. Se for true, o dado foi salvo, se false, não foi salvo.
// if( gravaDados_forma02( arquivo, leDados_forma02())
// {
// printf( "Gravado" );
// } else {
// printf( "Não gravado.");
//}
// Sempre depois a abertura de um arquivo o mesmo deve ser fechado.
// Consulta: http://devdocs.io/c/io/fclose
fclose( arquivo );
} else {
printf("Falhou!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment