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.

Anúncios

10 thoughts on “Manipulação de Ficheiros de texto em Linguagem C – leitura/escrita formatada

  1. 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

  2. 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?

  3. 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!!!!!

  4. 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!

  5. 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 “|”

  6. 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.

  7. Olá!!!

    Gostaria de uma ajuda: estou desenvolvendo um jogo que imprime a pontuação do jogador em um arquivo (ele cria um arquivo txt com o nome do jogador) para que posteriormente esta informação possa ser usada. Porém gostaria que o jogador não tivesse acesso ao arquivo txt criado, ou seja, ele não poderia alterar a sua pontuação. Resumindo: queria deixar este arquivo para somente leitura, mas lembrando que o programa irá imprimir nele novas pontuações do jogo. Como faço isso em c??? Grata!!!

  8. Olá!
    A resposta para este problema passa algures pela “encriptação” do tal txt.
    Existem muitos aplicativos/comandos que executam estas tarefas, como por exemplo: http://www.monkeyjob.com/FileMonk/FMExamp/Encrypt-Files.htm
    No seu caso, a solução passa por utilizar um “algoritmo de encriptação” para mascarar os dados escritos no txt … o que pode ser desde muito simples até extraordinariamente complexo.
    Para não complicar sugeria algo do tipo de trocar cada caracter no txt por outro de acordo com uma regrazinha muito simples … tipo:
    – os caracteres em posição par são trocados pelo caracter seguinte (ascii)
    – os caracteres em posição ímpar pelo caracter anterior.
    Por exemplo:
    “adoro promamacao”
    dava algo do tipo
    “bcpqo………”
    Desta forma, só tendo acesso ao código é que se pode entender “facilmente” como os dados foram mascarados.
    Espero ter ajudado.

  9. Boas, eu preciso de fazer um programa que dado 2 números e um operador, fazer essa operação.
    Exemplo : 67 1 + (No ficheiro de texto), teria de meter o operador no meio e fazer a conta e no output ter 67 + 1 = 68.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s