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", ®isto.numero);
while(registo.numero > 0){
printf("Nome: "); scanf("%s", registo.nome);
printf("Idade: "); scanf("%d", ®isto.idade);
fprintf(fp, "%d %s %d\n", registo.numero, registo.nome, registo.idade);
printf("\nNúmero: "); scanf("%d", ®isto.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", ®isto.numero, registo.nome, ®isto.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.
Janeiro 20, 2009 ás 6:14 pm
bem eu adoro que me ajuda se msm no no programa.
preciso um programa em ficheiros para o jogo quem quer ser milionario
Maio 23, 2009 ás 7:22 pm
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
Maio 24, 2009 ás 8:45 am
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?
Maio 24, 2009 ás 8:55 am
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!!!!!
Maio 24, 2009 ás 2:31 pm
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!
Maio 24, 2009 ás 2:35 pm
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 “|”
Maio 24, 2009 ás 7:33 pm
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.