Você está na página 1de 6

Lendo arquivos em C: As funes fgetc, fscanf e fgets

Agora que j aprendemos a escrever em arquivos em C, vamos aprender agora em nossa


apostila de C a outra parte: aprender como ler informaes dos arquivos!
Iremos aprender como ler caractere por caractere, ou um trecho pr-formatado ou linha
por linha.
Isso vai depender da necessidade de cada aplicativo em C.

fgetc() - Como ler caracteres de um


arquivo
Se voc leu o tutorial passado de nosso curso de C, vai notar que no tem muita
diferena nem dificuldade na leitura de informaes de um arquivo.
Quando estvamos trabalhando com os arquivos padres (lendo informaes do
teclado), usvamos funes como getchar, scanf e gets.
Aqui, iremos ensinar a usar funes correspondentes, porm para trabalhar com
arquivos que esto armazenados em nosso disco rgido.
A nica diferena entre leitura e escrita, a posio do arquivos que vamos ler.
Quando estvamos escrevendo, se usssemos o modo de abertura "w", escrevamos
desde o incio do arquivo.
Se fosse usando o "a", escrevamos ao final do arquivo.
J na leitura, vamos usar funes que iniciaro a leitura sempre do comeo do arquivo.
Quando usamos a funo fgetc, por exemplo, ele l o primeiro caractere e
automaticamente j se posiciona no prximo. Ao ler o prximo, o C j se prepara para
ler o prximo caractere do arquivo, e assim segue, at encontrar a constante EOF.
A sintaxe da funo fgetc :
int fgetc(FILE *arq)
Ela retorna um inteiro que representa o caractere, e EOF, que vale -1, caso aponte para
o fim do arquivo. E como os caracteres so representados por inteiros que vo de 0 at
255, um caractere no arquivo nunca ter o valor -1, somente entre 0 e 255.
E como comentamos, uma coisa importante que ocorre 'por debaixo dos panos' que
aps retornar um caractere, est funo j passa a apontar para o prximo caractere,
automaticamente, at encontrar -1 (EOF).

Exemplo de cdigo C - Programa que l o contedo de um arquivo,


caractere por caractere
Faa um programa que leia de um arquivo "poema.txt" e imprima na tela,
caractere por caractere.

Primeiramente, escreva algo no "poema.txt", pode ser um poema, seu nome completo,
endereo etc.
Escreva algo e coloque esse arquivo na mesma pasta do executvel.
Assim, nosso endereo simplesmente "poema.txt", e como queremos ler, vamos usar o
mtodo de abertura "r".
Declaramos uma varivel de nome "ch" do tipo char, que vai receber caractere por
caractere do arquivo.
Isso feito usando o seguinte cdigo:
ch=fgetc(arq)
E isso deve ser feito enquanto o caractere apontando no arquivo no for EOF.
Fazemos essa checagem assim:
(ch=fgetc(arq))!= EOF
Assim, nosso programa que mostra todo o contedo de um arquivo na tela, :
#include <stdio.h>
int main(void)
{
char url[]="poema.txt";
char ch;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o arquivo\n");
else
while( (ch=fgetc(arq))!= EOF )
putchar(ch);
fclose(arq);
return 0;
}

Exerccio resolvido - Contando o nmero de linhas de


um arquivo
Escreva um programa que conte o nmero de linha do arquivo da questo anterior.
O que caracteriza uma linha?
O caractere new line "\n".
Para contar quantas linhas tem um arquivo de texto, basta percorrermos todos os
caracteres do arquivo em busca dos "\n", pois cada caractere desse geralmente est no
final de uma linha.

Vamos usar o cdigo do exemplo passado deste tutorial para percorrer todos os
caracteres, e cada vez que encontrar um "\n" incrementamos a varivel "num",
inicializada com 0.
Nosso cdigo :
#include <stdio.h>
int main(void)
{
char url[]="poema.txt",
ch;
int num=0;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o
arquivo\n");
else
while( (ch=fgetc(arq))!= EOF )
if(ch == '\n')
num++;
printf("Existem %d linhas no arquivo\n", num);
fclose(arq);
return 0;
}

fscanf() - Lendo uma entrada formatada


Assim como possvel escrever de maneira formatada atravs das funes printf e
fprintf, tambm podemos ler de maneira formatada, como possvel na scanf, atravs
do uso da funo fscanf.
Isso particularmente interessante se tivermos um arquivo com um determinado
formato.
Ou seja, quando o contedo do arquivo obedecer um determinado padro.
Por exemplo, vamos supor que voc tenha uma lista com notas de 3 alunos.
Na primeira coluna as notas de Matemtica, na segunda as de Fsica e na terceira coluna
as notas de Qumica.
Cada linha representada como: "%f %f %f\n"
Ou seja: nmero, espao em branco, nmero, espao em branco, nmero.e o new line.
Este o formato, este o padro.
A sintaxe da fscanf :
int fscanf(FILE *arq, char *string_formatada)

Como as outras, retorna EOF caso no tenha conseguido fazer a leitura de maneria
correta.

Exemplo de cdigo - Como usar a fscanf


Suponha que tenhamos um arquivo de texto chamado "arquivo.txt" com o
seguinte contedo:
abc
def
ghi
jkl
Como usar a fscanf para l-lo?
Basta notar que o formato desse arquivo : caractere, espao, caractere, espao,
caractere e enter
Ou seja: "%c %c %c\n"
O formato se repete lina por linha, onde temos que receber 3 caracteres por linha.
Ento vamos salvar esses trs em trs variveis do tipo char e exibi-las.
Nosso cdigo para ler e exibir esses caracteres :
#include <stdio.h>
int main(void)
{
char url[]="arquivo.txt",
ch1, ch2, ch3;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o
arquivo\n");
else
while( (fscanf(arq,"%c %c %c\n", &ch1, &ch2,
&ch3))!=EOF )
printf("%c %c %c\n", ch1, ch2, ch3);
fclose(arq);
return 0;
}

Exemplo de cdigo - Nomes, notas e mdia


Em um arquivo chamado "notas.txt" est os dados dos nomes e notas de alunos.
Em cada linha h o nome do aluno, seguido de trs notas:
Maria 8 8 10
Jose 6 6 8
Carlos 7 9.5 7.5

Programador 10 10 10
Crie um programa que exiba o nome de cada aluno e sua mdia.
A primeira coisa que devemos fazer analisar o contedo do arquivo e procurar por
padres.
Nesse caso, o padro se repete em toda linha, pois todas as linhas so iguais: string,
espao, nmero, espao, nmero, espao, nmero, enter
Ou seja: "%s %f %f %f\n"
Como h um padro em toda linha, podemos usar a fscanf para armazenar esses dados.
Vamos precisar de uma string e trs floats.
Aps pegar esses dados, exibimos o nome do aluno e a mdia das notas.
Nosso cdigo em C fica:
#include <stdio.h>
int main(void)
{
char url[]="notas.txt",
nome[20];
float nota1, nota2, nota3;
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o
arquivo\n");
else
while( (fscanf(arq,"%s %f %f %f\n", nome, &nota1,
&nota2, &nota3))!=EOF )
printf("%s teve media %.2f\n", nome,
(nota1+nota2+nota3)/3);
fclose(arq);
return 0;
}

fgets() - Capturando linha


Usvamos a funo gets para capturar uma string do teclado do usurio.
Ela pegava do primeiro caractere at encontrar o new line("\n"), e colocava o caractere
delimitador ao final ("\0").
Muitas vezes interessante pegar uma linha inteira de um arquivo, principalmente se
nesse arquivo existir textos.
Para fazer esta tarefa, uma boa opo usar a funo fgets, cuja sintaxe :
char *fgets(char *minhaString, int numBytes, FILE *arq)

Essa funo vai abrir o arquivo apontado por arq e vai pegar do primeiro caractere at o
new line, ou at o limite de "numBytes" bytes e vai armazenar essa string na
"minhaString".
Ou seja, vamos usar ela para pegar cada linha de um arquivo e armazenar na forma de
string.
Por exemplo, escreva em um arquivo "dados.txt"o seguinte contedo:
"Meu nome: [escreva seu nome completo]
Moro em: [escreva seu endereo]
Estudo pelo C Progressivo
E pretendo ser programador C"
Agora vamos criar um programa que vai ler e exibir esses dados:
#include <stdio.h>
int main(void)
{
char url[]="dados.txt",
info[50];
FILE *arq;
arq = fopen(url, "r");
if(arq == NULL)
printf("Erro, nao foi possivel abrir o
arquivo\n");
else
while( (fgets(info, sizeof(info), arq))!=NULL )
printf("%s", info);
fclose(arq);
return 0;
}

Podemos usar cada linha dessas e armazenar em uma string diferente (string que guarda
o nome, outra que guarda o endereo, outra que guarda o CPF, RG etc, igual aqueles
formulrios que preenchemos na internet).
Vale notar que, como a fgets retorna uma string, para checar se chegamos ao fim do
arquivo, basta checarmos se o retorno dela diferente de NULL.