Arquivos em C
0
0

Arquivos em C

A figura abaixo exibe o conteúdo dos arquivos (texto e binário) armazenando os seguintes dados:

Grey
5 min
0
0
  • Arquivo é um conjunto de dados nomeados, armazenados e organizados em um meio de armazenamento de dados.
  • Por que usar arquivos? Permitem armazenar grande quantidade de informação;Dados não são perdidos (persistência dos dados);Acesso aos dados poder ser não seqüencial;Acesso concorrente aos dados (mais de um programa pode usar os dados ao mesmo tempo).
  • Permitem armazenar grande quantidade de informação;
  • Dados não são perdidos (persistência dos dados);
  • Acesso aos dados poder ser não seqüencial;
  • Acesso concorrente aos dados (mais de um programa pode usar os dados ao mesmo tempo).
  • Basicamente, a linguagem C trabalha com dois tipos de arquivos: de texto e binários. Arquivo texto : Armazenam caracteres que podem ser mostrados diretamente na tela ou modificados por um editor de textos simples como o Bloco de Notas.Arquivo binário : Armazena uma sequência de bits que está sujeita as convenções dos programas que o gerou. Ex: arquivos executáveis, arquivos compactados, arquivos de registros, etc.
  • Arquivo texto : Armazenam caracteres que podem ser mostrados diretamente na tela ou modificados por um editor de textos simples como o Bloco de Notas.
  • Arquivo binário : Armazena uma sequência de bits que está sujeita as convenções dos programas que o gerou. Ex: arquivos executáveis, arquivos compactados, arquivos de registros, etc.

A figura abaixo exibe o conteúdo dos arquivos (texto e binário) armazenando os seguintes dados:

struct
{
int matric;
char nome[10];
float salario;
} func;

Manipulando arquivos em C

  • Os protótipos dos comandos de manipulação de arquivos em C encontram-se definidos na biblioteca padrão sdtio.h.
  • Para se trabalhar com arquivos é necessário declarar uma variável ponteiro do tipo FILE. FILE *farq;
  • Para manipular um arquivo em C é necessário abrí-lo. Para tanto, a linguagem C possui o comando fopen.farq = fopen(char *Nome_do_arquivo, char *modo_de_abertura);
  • O primeiro parâmetro é o nome do arquivo. Pode-se trabalhar com caminhos absolutos ou relativos. > Caminho absoluto: descrição de um caminho desde o diretório raiz. C:\MinhaPasta\arquivo.txt > Caminho relativo: descrição de um caminho desde o diretório corrente (onde o programa está salvo) arquivo.txt ou ..\dados.txt
  • O segundo parâmetro define-se o modo de abertura:
Email image

Exemplo

FILE *farq;
farq = fopen("arquivo.txt", "rb");
if (farq == NULL) // <---- Testa se o arquivo foi aberto corretamente.
{
printf("Problemas na CRIACAO do arquivo\n");
return;
}
  • Ao terminar de usar o arquivo é necessário fechá-lo. Para isso usamos a função fclose(FILE *farq).
  • O ponteiro *farq indica que arquivo deve ser fechado. Após o seu fechamento o arquivo não pode ser manipulado.

Gravando e lendo caracteres em Arquivos C

  • Após a abertura do arquivo é possível Ler e/ou gravar dados nele.
  • A função fputc() possibilita a gravação de dados caracter a caracter.

int fputc(int ch, FILE *arq);

  • A função fgetc() possibilita a leitura de dados do arquivo caracter a caracter.

int fgetc(FILE *arq);

  • Quando não houver mais dados a serem lidos no arquivo, a fgetc devolve a constante EOF (end of file), que está definida na biblioteca stdio.h, indica o fim de um arquivo. Isso indica chegamos ao fim do arquivo e não se pode realizar a leitura dos dados. Em geral, o valor de EOF é igual −1.
  • Após a abertura do arquivo é necessário realizar o teste de fim de arquivo (o arquivo pode estar vazio):
if((fp = fopen("arquivo.txt","r")) == NULL){
printf( "Erro na abertura do arquivo");
exit(1);
}

O Exemplo a seguir exibe a gravação e leitura de dados caracter a caracter.

  • No comando fopen será criado o arquivo arqtexto.txt na pasta corrente
  • A string tentrada será gravada no arquivo caracter a caracter.
  • O arquivo será fecado e posteriormente aberto para leitura.
  • Utilizamos a função fgetc() para ler esses dados do arquivo caracter a caracter:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *farq;
int i;
char tentrada[50] = {"Teste de gravacao e leitura de dados-arquivo texto"};
char tsaida[50], car;
if((farq = fopen("arqtexto.txt","w")) == NULL){
printf( "Erro na abertura do arquivo");
exit(1);
}
for (i=0; i < strlen(tentrada); i++)
{
fputc(tentrada[i],farq);
}
fclose(farq);
farq = fopen("arqtexto.txt", "r");
if (farq == NULL) // Pode-se fazer o teste dessa forma
{
printf("Erro na abertura do arquivo");
exit(1);
}
printf("\n\nVou ler e mostrar o texto gravado....\n\n");
i=0;
car=fgetc(farq);
while (car!=EOF)
{
tsaida[i]=car;
printf("%c",tsaida[i]);
i++;
car =fgetc(farq);
}
fclose(farq);
}
  • A constante EOF pode ser substituida pela função feof() que realiza o teste de fim de arquivo. int feof(FILE *arq)
  • O teste do while do exemplo acima poderia ficar assim: while ( !feof (farq) )

Gravando e lendo cadeias de caracteres em arquivos C

  • Existem funções na linguagem C que permitem escrever fputs() e ler fgets() cadeias de caracteres.int fputs(char* cadeia, FILE *arq)
  • Esta função recebe como parâmetro uma cadeia de caracteres (string) e um ponteiro para o arquivo que queremos gravar.
  • Exemplo de um trecho de gravação de cadeia de caracteres
FILE *farq;
char tentrada[51] = {"Teste de gravacao e leitura de dados-arquivo texto"};
farq = fopen("arqtexto.txt", "w");
tsaida[50]='\0';
fputs(tentrada,farq);
fclose(farq);
  • Diferentemente da função de gravação, a função de leitura possui um parâmetro a mais para indicar o tamanho, isto é, o número máximo de caracteres que serão lidos.
  • Essa função pode retornar a cadeia de caracteres (ponteiro para o primeiro caractere da cadeia) ou NULL em caso de erro ou fim do arquivo.

int fgets(char* cadeia, int tamanho, FILE *arq)

  • Exemplo de um trecho de leitura de cadeia de caracteres
char tsaida[51];
farq = fopen("arqtexto.txt", "r");
fgets(tsaida, tam, farq);
printf("Foi lida a frase: %s", tsaida);
fclose(farq);

Gravando e lendo Blocos de dados em Arquivos C

  • Podemos escrever e ler blocos de dados em arquivos C através das funções: fwrite() e fread()
  • A função fwrite()

unsigned fwrite(void *bloco, int numero_de_bytes, int total, FILE *arq)

bloco: ponteiro para a região de memória na qual estão os dados; numero_de_bytes: tamanho de cada posição de memória a ser escrita; total: quantidade de blocos de memória de tamanho "numero_de_bytes" que devem ser escritos; arq: ponteiro associado ao arquivo onde os dados serão escritos.

Exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *farq;
int i;
char texto[51]={"Teste de gravacao e leitura de dados-arquivo texto"};
int vet[4] = {1,2,3,4};
texto[50]='\0';
farq = fopen("arqtexto.txt", "w");
fwrite(texto, sizeof(char), strlen(texto), farq); // grava a cadeia texto no arquivo
fwrite(vet, sizeof(int), 4, farq); // grava o vetor vet no arquivo
fclose(farq);
}
  • A função fread() é semelhante a fwrite() para realizar a leitura dos dados.

unsigned fread(void *bloco, int numero_de_bytes, int total, FILE *arq)

Exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *farq;
int i;
char textos[51];
int vets[4];
char texto[51]={"Teste de gravacao e leitura de dados-arquivo texto"};
int vet[4] = {1,2,3,4};
// Realiza a Criação do Arquivo e Gravação dos dados
texto[50]='\0';
farq = fopen("arqtexto.txt", "w");
fwrite(&texto, sizeof(char), strlen(texto), farq); // grava a cadeia texto no arquivo
fwrite(&vet, sizeof(int), 4, farq); // grava o vetor vet no arquivo
fclose(farq);
// Realiza a Leitura dos dados gravados
farq = fopen("arqtexto.txt", "r"); // Abre o arquivo para leitura
if(farq == NULL){
printf( "Erro na abertura do arquivo");
exit(1);
}
fread(&textos, sizeof(char), strlen(texto), farq); // lê a cadeia texto no arquivo
printf("\n\nTexto lido do Arquivo: %s\n\n", textos);
fread(&vets, sizeof(int), 4, farq); //lê os 4 números para o vetor vets no arquivo
printf("Digitos Armazenados no Arquivo: ");
for (i = 0; i < 4; i++) {
printf("%d ", vets[i]);
}
fclose(farq);
}
  • Os acessos aos dados em um arquivo geralmente é sequencial, mas é possível fazer buscas e acessos randômicos através da função fseek():
  • Esta função posiciona a leitura ou escrita no arquivo em tantos bytes, a partir de um ponto especificado.
  • A função fseek recebe 3 parâmetros fptr: o ponteiro para o arquivo;numbytes: é o total de bytes a partir do tipo a ser pulado;tipo: determina a partir de onde os numbytes de movimentação serão contados.
  • Os valores possíveis para tipo estão definidos em stdio.h e são:
Email image

Portanto, para mover numbytes a partir

  • do início do arquivo, tipo deve ser SEEK_SET
  • da posição atual, tipo deve ser SEEK_CUR
  • do final do arquivo, tipo deve ser SEEK_END
#include<stdio.h>
struct alunos {
int matric;
char nome[10];
int idade;
};
int main()
{
FILE *farq;
struct alunos al, alun[4] = {1, "Maria", 20, 2, "Ana", 19, 3, "Carlos", 16, 4, "Celso",19};
farq = fopen("arqtexto.txt", "wb");
fwrite(alun, sizeof(struct alunos), 4, farq); // grava o array de registros alunos
fclose(farq);
farq = fopen("arqtexto.txt", "rb");
fseek(farq, 3*sizeof(struct alunos), SEEK_SET); // posiciona a leitura no quarto registro
fread(&al, sizeof(struct alunos), 1, farq); // lê o quarto registro de aluno
printf("\n\n%d\n%s\n%d", al.matric, al.nome, al.idade);
fclose(farq);
}