FICHEIROS
Introdução
- de c
- Terminada a execução do programa, estes dados desaparecem
- O que interessa na gestão de dados, é armazenar os dados de forma permanente.
- Isto só se consegue armazenando os dados em ficheiros externos ao programa que executamos
- Em Ficheiros que podemos escrever, leitura, modificar e armazenar os dados nele contidos.
- E que mais tarde podemos recuperar para utilizar novamente.
- Vamos portanto aprender aqui como declarar, criar e manipular estes ficheiros.
Exemplo
Suponha que desenvolve um programa para a calcular a média aritmética da primeira prova de frequência de uma turma e passado algum tempo realiza uma segunda prova de frequência para a mesma turma e pretender calcular a média aritmética das classificações obtidas em ambas as provas. Será que tem de introduzir novamente os dados relativos à primeira prova de frequência?
Tipos de periféricos
Os dados de entrada para um programa podem ser fornecidos a partir de periféricos de entrada, tais como, teclado, rato, leitor de código de barras, etc.
Os dados de saída de um programa podem ser enviados para diversos periféricos de saída, tais como, monitor, impressora, etc.
Existem periféricos de entrada/saída, tais como, discos, que permitem operações de leitura/escrita.
Independentemente do tipo de periférico, a Linguagem C, processa todas as entradas e saídas de dados através de streams.
STREAMS
É um conjunto sequencial de dados, isto é, um conjunto de Bytes, sem qualquer estrutura interna.
Vantagem dos streams na sua utilização na entrada/saída de dados é que é independente do periférico que se está a utilizar.
Em C cada stream está ligado a um ficheiro, mas pode não corresponder fisicamente a um ficheiro existente em disco.
Tipos
de Ficheiros
Ficheiro texto
–
é
processado como uma sequência de caracteres ( contém texto
constituído por caracteres, pontuação, espaço em branco, tab, newLine \n)
Os caracteres dos ficheiros de texto
são representados no código ASCII e podem ser lidos ou escritos por qualquer
processador de texto em qualquer computador, tendo como grande vantagem
a portabilidade.
Ficheiro binário
–
é
processado como uma sequência de bytes, codificado em binário (caracteres existentes na tabela ASCII,
caracteres de controlo e caracteres especiais, caracteres sem representação
visível \0)
Num ficheiro binário os dados são
armazenados como bytes e a representação usada é a mesma que os dados binários
armazenados na memória central do computador. Em geral os dados binários não
são muito portáveis
Nota: Quer
os ficheiros binários quer os de texto armazenam os dados como sequências de
bits.
A diferença verifica-se no
modo como os programas lêem ou escrevem para estes ficheiros
A informação guardada em ficheiro pode ser acedida e gerida de dois
modos distintos:
Modo
sequencial - ficheiro de texto -
Neste modo os
elementos do ficheiro são acedidos sequencialmente, em posições
consecutivas. Os ficheiros de texto, constituídos por informação
estruturada em linhas, logo, elementos de comprimento variável terminados por
uma marca de fim de linha, são geridos em modo sequencial.
|
Declaração de ficheiros num programa em linguagem C:
FILE *nome_ficheiro_no_programa; // FILE em maiúsculas
Exemplo: FILE *fich; // fich é um apontador para o tipo FILE
Antes de criar ou abrir um ficheiro externo temos que declarar uma variável do tipo FILE que é nome interno no programa.
O que interessa aqui é este nome do ficheiro no interior do programa que vai ser usado para manipular o ficheiro em disco.
Operações básicas sobre ficheiros
Abertura de um ficheiro - Função fopen
O protótipo da função está no header file stdio.h
Ponteiro_tipo_FILE = fopen ( nomeFicheiroDisco , Mod oAcessoFic )
fich = fopen( localização \\nomeficheiro, modoacesso );
Exemplo:
fich = fopen (“conto.doc”, “w” ); // e indicamos qual é o modo de acesso
Cria e Abre o ficheiro e é feita uma relação entre o nome interno (“fich”) e o nome externo (“conto.doc”)
/* Modos de Acesso no momento de abrir um ficheiro com fopen() */
“r”- read: abre o ficheiro só para leitura. O ficheiro tem que existir em disco.
“w” – write: Abre o ficheiro para escrita; se existir o ficheiro será rescrito. Se não existir, cria o ficheiro
“a” – append : abre o ficheiro para escrever no fim do ficheiro; se não existir, cria o ficheiro
“r+” abertura do ficheiro para escrita e leitura; se existe reescreve;
“w+” abertura do ficheiro para escrita e leitura; se existe apaga e cria um novo;
“a+” abertura do ficheiro para escrita e leitura; adiciona no fim dum ficheiro existente
Por default, os ficheiros são abertos em modo de texto, pelo que o uso do modificador “t” não é necessário.
Modo Texto e Modo Binário
Por defeito, a abertura de um ficheiro é realizada considerando este como um ficheiro texto
Para abrir um ficheiro em modo binário é necessário acrescentar um b ao modo de abertura
Ex: “wb”
Ficheiro texto – texto constituído por caracteres, pontuação, espaço em branco, tab, newLine \n
Ficheiro binário – caracteres existentes na tabela ASCII, caracteres de controlo e caracteres especiais, caracteres sem representação visível \0,
EXERCÍCIO: Complete os programas
a) programa para escrever num ficheiro de texto
#include <stdio.h>
main()
{
FILE * ;
=fopen( “texto.txt”, ” ” );
}
b) programa para ler um ficheiro binário
#include <stdio.h>
main()
{
*fich ;
fich= (“Exerc.txt”,” ”);
fclose( ) ;
}
Fecho de um ficheiro função fclose ();
Utiliza-se: fclose( fich ); //fecha o ficheiro fich em que a variável apontador para FILE
Funções de escrita /Leitura de dados num ficheiro
fprintf escreve no ficheiro fprintf (nome_ficheiro, formatação saída + texto, variáveis )
fscanf lê do ficheiro fscanf (nome_ficheiro, formatação_entrada, variáveis)
fputc() – escreve 1 caracter no ficheiro fputc(caracter , ficheiro);
fgetc() – leitura de 1 caracter do ficheiro caracter= fgetc(ficheiro);
fputs() – inserir 1 string no ficheiro fputs(string, ficheiro);
fgets() – leitura de 1 string: parâmetros de fgets (string, tamanho, ficheiro);
Recordar funções
putc(caracter) ; puts(string);
getc() gets ()
EXEMPLO
#include <stdio.h>
main()
{
char nome[20];
FILE *f;
f = fopen("Texto.txt", "w"); //abre arquivo para escrita
//pede ao utilizador e lê o nome introduzido
printf("Digite 1 nome: ");
gets(nome);
//escreve no ficheiro uma string que está na variável nome
fprintf (f, “%s “, nome);
fclose( f ); //fecha arquivo criado
}
#include <stdio.h>
main()
{
char nome[20];
FILE *f;
f=fopen("Texto.txt","r");
fscanf(f, "%s", nome );
printf("Nome do ficheiro: %s \n", nome );
fclose(f);
}
Exercício1: //pedir ao utilizador o nome e a nota de PSI que deseja e escrever os dados no ecrã
#include <stdio.h>
main()
{ char nome[20]; FILE *f;
f = fopen(" Dados.dat", "w");
printf(“ Nome: “);
gets(nome);
do
{ printf(“ Nota: “);
scanf(“%d”, ¬a);
} while ( nota <0 || nota >20); //faz enquanto nota errada
fprintf(f, "%s \n %d \n ", nome, nota);
fclose( f );
}
Exercício 2: Abrir ficheiro e ler o nome e a nota e apresentar os dados no ecrã
Resolução
#include <stdio.h> /* Criar um ficheiro de texto desde o teclado. Escreva um conto */
#include <string.h> // Utilização de fopen() e fprint();
void main()
{ FILE *fich; /* Declaramos um ponteiro a um ficheiro */
char linha[80];
int total = 1;
/* Abaixo: abrir novo ficheiro para escrita de texto verificando se OK */
fich = fopen("conto.doc", "w+t"));
//Ler 4 linhas de texto
for ( i=1; i<=4 ; i++ )
{ printf("\n escreva uma linha de texto do conto: ");
gets(linha);
fprintf( fich, "%s\n", linha);
}
Podemos utilizar este código se quisermos que escreva uma mensagem de erro se não for possível abrir o ficheiro
if ( fich == NULL)
{ printf( "não podemos abrir o ficheiro \n");
exit(1);
}
/* Verificamos se foi possível abrir o ficheiro ou não */
Usou-se a função exit(int num) (de stdlib.h) que permite terminar um programa,
devolvendo números diferentes, conforme o tipo de erro, que podem ser lidos
pelo sistema operativo.
FICHA DE TRABALHO
1. Qual a função que serve para criar ou abrir um ficheiro?________________ E qual a função que fecha um ficheiro?____________
2. Indique 2 funções que permitem escrever texto num ficheiro de texto__________________________________________________
3. Indique 2 funções que permitem ler texto de um ficheiro de texto_________________________________________________
4. Qual o ciclo/estrutura de repetição que utiliza para validar a entrada de um valor, isto é, que obriga a repetir quando um valor não é válido?__________________________________________________________________
5. Para indicar o modo de acesso de escrita utiliza-se____, e para o modo de acesso de leitura utiliza-se _____ e acrescentar ____
6. Declare uma variável apontador do tipo ficheiro_________________________________________
7. Qual a função que detecta o fim do ficheiro?__________________________
8. Faça um programa em C que peça ao utilizador o seu clube de futebol e depois escreva no ficheiro a resposta do utilizador.
9. Faça um programa em C que leia o conteúdo do ficheiro criado no programa anterior e apresente-o no ecrã.
10. Faça um programa que peça ao utilizador que ponha em prática a sua veia poética... e que introduza 4 versos de um poema
Função feof( ficheiro) Fim de Ficheiro - End Of File - EOF - detecta fim do ficheiro
Imagine o conto criado anteriormente. Agora vamos ler caracter a caracter… usar função fgetc e feof
#include <stdio.h>
void main()
{char c; FILE *fich;
fich = fopen (“c:\\conto.doc", "r"); /* abrir o ficheiro para leitura */
while ( !( feof ( fich) ) /*REPETE enquanto não encontra fim do ficheiro */
{ c= fgetc (fich ); /* devolve cada caracter lido do ficheiro*/
printf("%c", c); // escreve no ecrã o caracter lido anteriormente do ficheiro
}
fclose(fich); /* fechar o ficheiro previamente aberto */
}
//pedir o nome do ficheiro ao utilizador e abri-lo e escrever o que nele está contido
#include <stdio.h>
void main()
{ char nm[20] , ch ; FILE *fich;
printf( “\n Introduza o nome do ficheiro que quer abrir “);
scanf(“%s”, nm);
fich =fopen(nm, “r”); //abre ficheiro para leitura
if ( fich ==NULL)
{printf(“\n Impossível abrir ficheiro \n ”); exit(0); }
while ( ! feof (fich) )
{ ch= fgetc(fich); /* devolve próximo caracter do ‘stream’ */
printf("%c", ch); // escreve no ecrã caracter a caracter
}
fclose(fich);
}
Ler uma linha de um ficheiro fgets( variavel_string, strlen(tipo)+1, ficheiro)
Exercício
Escrever um programa que crie um ficheiro de texto contendo 4
nomes de cidades e respectivas temperaturas médias num dado dia.
Exercício Ler o conteúdo do ficheiro criado no exemplo anterior. Determinar média.
outros EXERCÍCIOS DE FICHEIROS DE TEXTO
1) // Pedir nomes e idades de 10 alunos e escrever todas as informações num ficheiro
2) /Abrir o ficheiro Alunos; escrever os dados no ecrã; determinar a média de notas ;
3) Abrir ficheiro e escrever só os alunos com positiva
.
4) Faça um programa em C
que peça ao utilizador o nome e idade de n pessoas e depois escreva os dados num ficheiro texto DadosID.txt
5) Programa em C que leia o
conteúdo do ficheiro criado no programa anterior e apresente-o os dados no ecrã.
Determine a média de idades. Determine quantos alunos são maiores de idade.
Determine a média de idades. Determine quantos alunos são maiores de idade.
Processamento de ficheiros em binário
Os ficheiros de texto contém ‘\n’ (mudança de linha) que identifica e separa os caracteres existentes no ficheiro; estão organizados por linhas
Ficheiros binários –não são de texto- são ficheiros de dados, executáveis, jogos, etc..
Não estão organizados por linhas;
São usadas operações de Acesso Directo utilizadas só para ficheiros binários.
Podemos escrever dados em blocos de memória em disco- por exemplo, escrever um vector completo de uma vez só em disco.
Função de leitura que permitem acesso directo: fread
Função de escrita que permitem acesso directo: fwrite
fwrite ( variável , sizeof ( tipo ), n_elementos , ficheiro); /* escreve em ficheiro com sizeof bytes */
fread ( variaável , sizeof( tipo ), n_elementos , ficheiro ) ; /* Ler sizeof bytes do ficheiro */
// as funções devolvem o nº de valores que leram
Exercício
Programa que leia para um vector 10 nºs inteiros; e escreva esses valores em disco no ficheiro “dadosvector.txt”
main ()
{ FILE *f; int V[10], i ;
// ler dados para vector
for (i=0; i<=9 ; i++ )
{ printf (" Indique o %dº número : ");
scanf("%d", &V [i] ) ;
}
f = fopen(“dadosvector.txt”, “wb”); //acrescenta-se ao w um b de binário
fwrite ( V, sizeof(int) , 10, f ); // vector, sizeof(int), 10 elementos, ficheiro
fclose(f);
}
Exercício:
Programa que leia do ficheiro em disco o vector de 10 elementos e mostra-os no ecrã
main ()
{ FILE *f; int V[10], i ;
// ler dados para vector
f= fopen(“dadosvector.txt”, “rb”); //acrescenta-se ao r um b de binário
fread ( V, sizeof(int) , 10, f ); // vector, sizeof(int), 10 elementos, ficheiro
//escreve o código no ecrã os elementos do vector
fclose(f);
}
// não de usa EOF pois pode dar erro
Exercício: /* Programa para criar uma ficha de uma pessoa -- ler os dados --de 3 pessoas */
//Se houver problemas na leitura de dados do tipo char - Utilizar fflush(stdin);
Exercício:
programa que leia do ficheiro em disco os 10 elementos mas sem recorrer ao vector, e mostrar-los um a um no ecrã
// variável simples necessita de & (endereço)
while ( fread ( &num , sizeof(int) , 1, f ) ) // lê 1 elemento do ficheiro
printf( “ %d \n ” , num ); //escreve no ecrã
// não de usa EOF pois pode dar erro
Estruturas: typedef, struct
#include <stdio.h>
#include <string.h>
typedef struct ficha
{ char nome[35];
int idade;
char telefone[10]; // declaração de 3 campos
};
// função para Ler dos Dados de 1 pessoa
ficha Ler_ficha_Pessoa( )
{ ficha p ; // p é uma variável do tipo struct ficha com 3 campos
printf("\nNome: "); gets( p. nome);
printf("idade: "); scanf("%d", &p.idade); // fflush(stdin);
printf("telefone: "); scanf("%s", p.telefone); //fflush(stdin);
return (p);
} /* ---- devolve a ficha (dados) de uma pessoa ----*/
void Escreve_Dados_Pessoa( ficha p ) // Entra 1 ficha (dados) de 1 pessoa e escreve esses dados
{ printf("\n Nome: %s", p.nome);
printf("\n telefone:%s", p.telefone);
printf("\n idade: %d", p.idade);
}
void main()
{ ficha pessoas[3] ; /*criamos um array com o novo tipo ficha: um array de estruturas */
for (int i = 0; i < 3; i++)
{ printf("\nPor Favor dê os dados da %dª pessoa:", i+1 );
pessoas[ i ] = Ler_ficha_Pessoa(); // ou
// printf("\nNome: "); gets( pessoas[ i ]. nome);
// printf("idade: "); scanf("%d", &pessoas[ i ].idade); // fflush(stdin);
// printf("telefone: "); scanf("%s", pessoas[ i ].telefone); //fflush(stdin);
}
printf("\nDados das Pessoas registadas: ");
for (i=0; i < 3; i++)
Escreve_Dados_Pessoa ( pessoas[i] ); //a função recebe 1 ficha - argumento- e escreve os dados
} //fim
Se o ficheiro stdin tinha output pendente para escrever, esta função escreve os dados pendentes. Em termos práticos limpa o teclado. Utilizada porque scanf() as vezes cria problemas.
Exercício:
/* Programa que escreve os dados –ficha- de 3 alunos do ficheiro “alunos” */
#include <stdio.h>
#include <conio.h>
typedef struct ficha //estrutura com 3 campos
{ char nome[30]; int idade; float peso;
}
ficha Ler_Dados_Aluno (ficha a)
{ printf("\nNome: "); gets(a.nome); fflush(stdin);
printf(" idade: "); scanf("%d", &a.idade); fflush(stdin);
printf(" peso: "); scanf("%f", &a.peso); fflush(stdin);
return (a);
} /*--------------------------------------------------------------------*/
void main ( )
{ FILE *fich ; ficha aluno;
fich = fopen ("\\Dados", "w+b") ;
for (int i =1; i < 4;i++)
{
printf("\nPor Favor dê os dados do %dº aluno:", i );
printf("\nNome: "); gets( aluno.nome ); // fflush(stdin);
printf(" idade: "); scanf("%d", &aluno.idade); // fflush(stdin);
printf(" peso: "); scanf("%f", &aluno.peso); // fflush(stdin);
fwrite (&aluno, sizeof (ficha), 1, fich); /* escreve aluno em ficheiro com sizeof bytes */
} //pode ser fwrite (&aluno, sizeof (aluno), 1, ficheiro);
fclose(fich);
} /*-------------------------------------------------------------------*/
fwrite( endereço_registo, tamanho_registo, 1, ficheiro) ;
fread( endereço_registo, tamanho_registo, 1, ficheiro) ;
Exercício:
/* Programa que vai ler as 3 fichas criadas no ficheiro “alunos” */
#include <stdio.h>
#include <conio.h>
#include <string.h>
typedef struct ficha
{ char nome[30]; int idade; float peso;
} ;
void Escreve_Dados_Aluno (ficha a)
{ printf("\nNome: %s", a.nome );
printf("\t idade: %d", a.idade );
printf("\t peso: %.1f", a.peso) ;
}
void main(void)
{ FILE *fich; ficha aluno; int i;
if ((fich= fopen("\\Dados", "r+b")) == NULL)
{ printf ( "Não podemos abrir ficheiro alunos. \n");
exit(1);
}
while ( fread (&aluno, sizeof(ficha), 1, fich ) )
Escreve_Dados_Aluno ( aluno) ;
fclose(fich);
}
Exercício:
// programa que utiliza fseek() mover o ponteiro f no stream
Ficheiros I/O -- fread(), fwrite(), fseek()
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{ char s1[50]; FILE *f; /* declara um ponteiro ficheiro */
char frase[ ] = "Isto é um teste para os meninos de Informática.";
if (( f = fopen("\\mensagem", "w+t")) == NULL)
{ printf("Não pode abrir ficheiro para escrever.\n");
exit(0);
}
fwrite (frase, strlen(frase)+1 , 1, f ) ; // escreve conteúdo de frase no stream f
// após escrever em f, o ponteiro aponta ao fim de f
fseek ( f , SEEK_SET, 0); // recolocamos o ponteiro de f apontando ao seu byte 0
fread ( s1 , strlen(frase)+1, 1, f ); // ler mensagem do ficheiro e colocar na string s1
printf("%s \n", s1 ); // Imprime o conteúdo da string s1
fflush(f);
fclose(f);
}
Ficheiros I/O: acesso directo a um registo
typedef struct ficha
{ char nome[30]; int idade; float peso;
} ;
void Escreve_Dados_Aluno (ficha a)
{ printf("\nNome: %s", a.nome );
printf("\t idade: %d", a.idade );
printf("\t peso: %.1f", a.peso) ;
}
void main(void)
{ int pos, n ; FILE *fich
; ficha aluno;
if ((fich = fopen("\\Dados", "r+b")) == NULL)
{ fprintf (stderr, "Não podemos abrir ficheiro clientes. \n");
return;
}
printf(“\n Indique número do cliente sff: “);
scanf(“%d”, &n);
fseek( fich, sizeof (ficha )*(n-1), SEEK_SET);
if ( ! ( fread (&aluno, sizeof(ficha), 1, fich) ) )
printf("\n Erro na leitura de alunos");
printf(“\n\n Dados do %d aluno \n “, n);
Escreve_Dados_Aluno ( aluno);
fclose(fich);
}
Pedir versos ao utilizador e escrevê-los num ficheiro texto - pára até digitar tecla ESC
break; // se estiver dentro de um menu sai do switch
}
getch();
}
Pedir versos ao utilizador e escrevê-los num ficheiro texto - pára até digitar tecla ESC
#include<dos.h>
#include<conio.h>
#include <stdio.h>
#define Esc_Key 27#include<conio.h>
#include <stdio.h>
main()
{
while ( 1) //kbhit()
{ // pede e lê o verso
{
while ( 1) //kbhit()
{ // pede e lê o verso
// escreve o verso dado pelo utilizador no ficheiro
if (getch()==Esc_Key) break; // se estiver dentro de um menu sai do switch
// usar exit(1); em vez de break; se for um programa sem menu para terminar o programa ;
getch();
}
Sem comentários:
Enviar um comentário