Manipulação de Ficheiros de texto em Linguagem C – leitura/escrita formatada

A manipulação de ficheiros de texto pode ser feita mediante uma abordagem caracter-a-caracter, que à partida cobre todas as necessidade do programador em termos de leitura e escrita.

No entanto, e para algumas situações específicas, pode recorrer-se às funções fscanf e fprintf para realizar as operações de input/output com algum tipo de formatação.

fprintf – Escreve dados no ficheiro num formato indicado

Protótipo: int fprintf(FILE *nomeficheiro, const char *formato, …)

Observações:

  • Devolve EOF caso seja detectado o fim do ficheiro;
  • Devolve o número de parâmetros que conseguiu ler com sucesso;
  • Deve ser usada apenas para ficheiros de texto.

Exemplo de escrita 1:

#include <stdio.h>
int main(int argc, char *argv[]){

	FILE *fp;

	int a=1;
	char b[30]="maria";
	float c=2.3;

	if(argc == 2){
		fp = fopen(argv[1], "w");
		fprintf(fp, "%d %s %.1f", a, b, c);
		fclose(fp);
	}
	else
		printf("É necessário especificar um nome de ficheiro.\n");
	return 0;
}

Observações:

  • A operação de escrita só é executada se fornecermos o nome do ficheiro a criar;
  • O ficheiro criado irá conter um registo(linha) com informação sobre uma pessoa.

Exemplo de escrita 2:

O exemplo seguinte aceita registos formados pelos campos número, nome e idade e escreve-os num ficheiro. A leitura dos dados termina se fornecermos um número de aluno negativo.

/* Nome do programa: fprintf_avancado */
#include <stdio.h>

typedef struct {
	int numero;
	char nome[20];
	int idade;
} ALUNO;

int main(int argc, char*argv[]){

	FILE *fp;
	ALUNO registo;

	/* verificar se o comando foi invocado com o nome do ficheiro */
	if (argc != 2){
		printf("Modo de utilização: %s nome_ficheiro\n", argv[0]);
		return 1;	/* terminar o programa sem sucesso */
	}

	/* criar ficheiro */
	fp = fopen(argv[1], "w");

	/* inserir dados - terminar o input com uma número de aluno negativo ou nulo */
	printf("Introduza os dados relativos aos alunos.\n");
	printf("Para terminar introduza um número de aluno negativo.\n");
	printf("\nNúmero: "); scanf("%d", &registo.numero);
	while(registo.numero > 0){
		printf("Nome: "); scanf("%s", registo.nome);
		printf("Idade: "); scanf("%d", &registo.idade);
		fprintf(fp, "%d %s %d\n", registo.numero, registo.nome, registo.idade);
		printf("\nNúmero: "); scanf("%d", &registo.numero);
	}

	/* fechar o ficheiro */
	fclose(fp);

	/* terminar o programa com sucesso */
	return 0;

}

fscanf – Lê dados do ficheiro no formato indicado

Protótipo: int fscanf(FILE *nomeficheiro, const char *formato, …)

Observações:

  • Devolve EOF caso seja detectado o fim do ficheiro;
  • Devolve o número de parâmetros que conseguiu ler com sucesso;
  • Deve ser usada apenas para ficheiros de texto;
  • É em tudo semelhante à função scanf, mas é especificado o stream a ser utilizado.

Exemplo de leitura 1:

#include <stdio.h>
int main(int argc, char *argv[]){

	FILE *fp;

	int a;
	char b[30];
	float c;

	if((fp = fopen(argv[1], "r"))!=NULL){
		fscanf(fp, "%d %s %f", &a, b, &c);
		printf("a = %d\n", a);
		printf("b = %s\n", b);
		printf("c = %.1f\n", c);
		fclose(fp);
	}
	else
		printf("O ficheiro especificado não existe!\n");
	return 0;
}

Exemplo de leitura 2:

O exemplo seguinte lê os dados armazenados no ficheiro criado pelo Exemplo de escrita 2. Não se esqueça de fornecer o mesmo nome de ficheiro quando testar este código.

/* Nome do programa: fscanf_avancado */
#include <stdio.h>

typedef struct {
	int numero;
	char nome[20];
	int idade;
} ALUNO;

int main(int argc, char*argv[]){

	FILE *fp;
	ALUNO registo;

	/* verificar se o comando foi invocado com o nome do ficheiro */
	if (argc != 2){
		printf("Modo de utilização: %s nome_ficheiro\n", argv[0]);
		return 1;	/* terminar o programa sem sucesso */
	}

	/* Abrir ficheiro caso exista */
	if((fp = fopen(argv[1], "r"))==NULL){
		printf("ERRO!\nO Ficheiro %s não existe.\n", argv[1]);
	   return 1;
	}

	/* mostrar os dados armazenados com o programa fprintf_avancado */
	while(fscanf(fp, "%d %s %d",	&registo.numero, registo.nome, &registo.idade)==3){
		printf("%d %s %d\n", registo.numero, registo.nome, registo.idade);
	}

	/* fechar o ficheiro */
	fclose(fp);

	/* terminar o programa com sucesso */
	return 0;

}

Observações finais

Como é evidente não fica tudo dito aqui, mas sinceramente para aplicações mais complexas esta não será a melhor abordagem.

7 Respostas para “Manipulação de Ficheiros de texto em Linguagem C – leitura/escrita formatada”

  1. pedro Diz:

    bem eu adoro que me ajuda se msm no no programa.
    preciso um programa em ficheiros para o jogo quem quer ser milionario

  2. Sara Diz:

    Descobri este site porque estou a tentar perceber como leio de um ficheiro em C em que exista o separador “|”. Por linha do ficheiro existe : frase1|frase2|frase3. Como as frases têm palavras separadas por espaços, quem criou o ficheiro colocou o separador “|” e não estou a conseguir ler.

    Se me puder dar umas dicas era excelente. Obrigado

  3. Graciano Torrão Diz:

    Não sei se estou a perceber o enunciado, mas lendo caracter a caracter uma frase termina sempre que se encontra “|” ou o “\n” certo?

  4. Sara Diz:

    Bom Dia

    O ficheiro de texto tem a seguinte informação por linha:
    Nome | Morada | codigo postal

    O “|” separa as três strings.

    Exemplo:

    Sandra Gomes | Rua da Quitinha | 1879 Cidade
    Carlos Santos | Av. Pedro Guimaraes | 1500 Lisboa

    o \n indica-me que a linha do ficheiro chegou ao fim. O meu problema é conseguir ler dizendo que o | separa as strings.

    Obrigado!!!!!

  5. Graciano Torrão Diz:

    Se eu tivesse que resolver este problema fazia mesmo a “tal” abordagem caracter a caracter ( getc, fgetc, putc e fputc) … é mais simples e funciona para todos os casos.
    Depois temos outras abordagem mais arriscada (linha a linha ou formatada).
    Encontrei este link que resume as funções a utilizar ( http://www.cs.swarthmore.edu/~newhall/unixhelp/C_files.html ) e as 3 abordagens que referi.
    Entretanto pode ser que algum especialista passe por aqui e tenha uma ideia melhor (que é sinónimo de mais simples) :)
    Bom trabalho!

  6. Graciano Torrão Diz:

    fscanf(infile, “%d,%c”, &x, &c); // read an int & char from file where int and
    // char are separated by a comma

    Ou então isto … e trocar a “,” pelo “|”

  7. Sara Diz:

    Boa Tarde

    Já experimentei e não funciona. Por exemplo se eu tiver na primeira linha do ficheiro “Bom Dia|Boa Tarde|sim” assim que apanha o espaço considera que a string chegou ao fim.
    O fscanf considera o espaço ou virgula ou | como final de string. Acho que terei de equacionar mesmo a abordagem do caracter a caracter, mas com 3 strings por linha é capaz de ficar o código um pouco extenso.

    De qualquer forma o meu muito obrigado pela atenção e este blog faz parte já dos meus repositórios a consultar.


Deixar uma Resposta