Programação MEAer e LEE Bertinho Andrade da Costa 2010/2011 1º Semestre Instituto Superior Técnico Manipulação de ficheiros de texto Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 1
Sumário Ficheiros Motivação Operações Ficheiros de texto e binários Manipulação de ficheiros de texto Abertura Encerramento Ficheiros: stdin, stdout, stderr Escrita Leitura Outras funções Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 2
Ficheiros Motivação: Até agora os programas que foram desenvolvidos limitavam-se a ler dados do teclado, efectuando em seguida o respectivo processamento, seguindo-se a escrira dos resultados no ecrã. Suponha o caso de um banco onde são realizadas transacções, isto é, movimentação de dinheiro. Neste caso é necessário registar os movimentos das contas. Não é suficiente mostrar no ecrã a informação da transacção. Por motivos legais e de bom funcionamento do banco, os registos devem ter a duração de alguns anos. A linguagem C disponibiliza mecanismos que permitem guardar informação no disco rígido do computador. Desse modo o tempo de vida da informação, que é guardada no disco rígido, passa a ser independente do tempo de execução de um programa. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 3
Ficheiros - Operações A informação quando é armazenada num disco rígido (ou noutro dispositivo de memória persistente) é colocada em compartimentos, cada compartimento constitui um ficheiro. Os ficheiros são utilizados para guardar dados númericos ou texto. Essa informação é representada através de uma sequência de símbolos (caracteres - bytes) Os ficheiros são elementos externos aos programas. Para se ter acesso aos dados que existem num ficheiro é necessário realizar uma ligação entre o programa e o ficheiro. As operações principais, válidas, sobre ficheiros são: Abertura de um ficheiro, para leitura ou para escrita. Operação de leitura ou operação de escrita Operação de encerramento/fecho de um ficheiro Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 4
Ficheiros - Buffer Quando o computador lê dados de um ficheiro, ele executa uma cópia de dados do dispositivo externo (disco) para a memória do computador. Quando o computador escreve dados para um ficheiro passa a informação que está em memória para o dispositivo externo. Regra geral os dados são guardados numa zona de memória temporária especial denominada de buffer. O buffer permite adaptar a velocidade de trabalho do processador (rápido) com a velocidade de trabalho da memória (mais lenta). Em C o fluxo de dados, uma sequência de elementos que é gerada ao longo do tempo é denomidada de stream. A cada instante só está disponível um único elemento do fluxo, o elemento corrente. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 5
Ficheiros - Operações Como os ficheiros existente separadamente dos programas executáveis é necessário estabelecer uma ligação entre um programa e um ficheiro de modo a ser possível aceder aos dados que estão no ficheiro. A ligação é realizada com o auxílio de uma tabela file table. Na linguagem C, a manipulação de ficheiros é realizada através do tipo FILE que está definido em stdio.h. Um programa para ter acesso a um ficheiro tem de declarar uma variável do tipo FILE *, o nome da variável deve respeitar as regras dos identificadores, como exemplo FILE *fp; fp é uma abreviatura de file pointer, mas também pode ser utilizado FILE *file1; Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 6
Ficheiros - Tipos Os ficheiros são classificados em dois tipos: Ficheiro de texto : São todos os ficheiros que em princípio podem ser lidos por um editor de texto, como o gedit, xemacs no Linux ou o notepad no Window. Um ficheiro de texto consiste numa sequência de caracteres, (normamelmente é utilizado o código ASCII). O ficheiro é terminado com um carácter especial, o carácter fim de ficheiro que em Linux/Unix é o Ctrl-D e no Windows é o Ctrl-Z. Ficheiros binários: São ficheiros cujo conteúdo pode corresponder a uma cópia da zona de memória de dados de um programa ou então podem conter código executável de programas, ou formatos de dados especiais cuja representação não utiliza o código ASCII. O formato dessa informação depende do tipo de representação interna do computador, como tal não é acessível através dos editores normais. Se se tentar abrir um ficheiro binário com um editor de texto é provável que sejam apresentados símbolos com um aspecto fora do vulgar. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 7
Manipulação de Ficheiros A manipulção dos ficheiros é feita através de funções cujos protótipos estão no stdio.h Nesta apresentação só são abordados os ficheiros de texto, são os mais importantes para os trabalhos que se pretende realizar na cadeira. Para se poder escrever ou ler informação para um ficheiro ou de um ficheiro é necessário: Abrir o ficheiro, É necessário especificar o caminho e nome do ficheiro. É necessário especificar o modo de abertura Utilizar a função que permita escrever/ler dados no ficheiro Fechar o ficheiro após a informação ter sido escrita/lida. Nota: O acesso à informação é realizado de forma sequêncial. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 8
Abertura de um Ficheiro A abertura de um ficheiro é realizada com a função cujo protótipo se apresenta: FILE *fopen(const char *filename, const char *mode); filename - é um apontador para o vector string (ou cadeia de caracteres constante) que tem o nome do ficheiro. mode - Permite definir o modo de abertura do ficheiro w - Modo de escrita, (write). Cria o ficheiro se não existir, ou apaga o ficheiro se já existir. r - Modo de leitura, (read). a - Modo de escrita em que permite acrescentar dados no fim do ficheiro, (append). A função retorna um apontador para um objecto do tipo FILE, que é utilizado por outras funções para lerem ou escreverem dados. Se ocorreu algum erro no processo de abertura então a função devolve o valor NULL (endereço nulo). O valor NULL, é genérico, como tal pode ser comparado com o conteúdo de apontadores de tipos diversos Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 9
Encerramento de um Ficheiro O encerramento de um ficheiro é realizado com a função cujo protótipo se apresenta: int fclose(file *stream); stream - representa o canal de acesso ao ficheiro, isto é, o apontador que foi devolvido pela função fopen( ). A função devolve 0 se teve sucesso e devolve -1 se não consegui fechar o ficheiro. int feof(file *stream); Permite verificar se se alcançou o fim de ficheiro. Retorna o valor zero se não é o fim de ficheiro. Retorna um valor diferente de zero se é o fim de ficheiro. Atenção: A função só indica o fim de ficheiro no caso em que o fim do ficheiro foi alcançado durante a execução a última operação de leitura ou de escrita. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 10
Ficheiros: stdin, stdout e stderr Em C, existem três ficheiros de texto que são abertos automaticamente sem que o programador tenha que efectuar a abertura explícita deles e que também são fechados quando o programa termina. São eles: stdin - é um ficheiro que é associado ao teclado. O teclado pode ser visto como um dispositivo gerador, uma fonte, de caracteres. stdout - é um ficheiro que é associado ao ecrã. O ecrã pode ser visto como dispositivo que guarda caracteres durante algum tempo. stderr - é um ficheiro que normalmente está associado ao ecrã e que é utilizado para receber mensagens de erro. A manipulação desses ficheiros, isto é, a leitura e a escrita de caracteres são realizadas através das funções: printf( ) - escreve no ficheiro stdout scanf( ) - lê a partir do ficheiro stdin Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 11
Ficheiros - Escrita Na escrita de ficheiros há uma função que é similar ao printf: int fprintf(file *stream, const char *format,...); stream - representa o canal de acesso ao ficheiro, isto é, o apontador que foi devolvido pela função fopen( ). O 2º argumento representa a cadeia de caracteres constante e é do mesmo género que a do printf.... - Significa que a função pode receber um conjunto variável de argumentos, por exemplo uma ou mais variáveis. A função retorna um valor inteiro que representa o número de argumentos que conseguiu escrever. Retorna um número negativo se ocorreu algum erro. NOTA: A função fprintf com o stream = stdout é equivalente ao printf. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 12
Ficheiros - Escrita Programa exemplo para escrita num ficheiro. #include <stdio.h> #include <math.h> int main(void) { const float PI = 3.14; int i; float y, x; FILE *fp; /* Abertura e teste do ficheiro */ fp = fopen ("seno.txt", "w"); if (fp == NULL) { fprintf(stdout, "Erro na abertura do ficheiro.\n"); return 0; } /* Calcula e guarda os valores */ for (i=0; i <=90; i = i + 10) { x = PI/180 * i; y = sin(x); fprintf (fp, "seno(%f)=%f\n", x, y); } } /* Fecha o ficheiro */ fclose(fp); fprintf(stdout, "Fim do programa n"); return 0; Ficheiro: seno.txt seno(0.000000)=0.000000 seno(0.174444)=0.173561 seno(0.348889)=0.341854 seno(0.523333)=0.499770 seno(0.697778)=0.642516 seno(0.872222)=0.765760 seno(1.046667)=0.865760 seno(1.221111)=0.939481 seno(1.395556)=0.984685 seno(1.570000)=1.000000 Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 13
Ficheiros - Leitura Na leitura de ficheiros há uma função que é similar ao scanf: int fscanf(file *stream, const char *format,...); stream - representa o canal de acesso ao ficheiro, isto é, o apontador que foi devolvido pela função fopen( ). O 2º argumento representa a cadeia de caracteres constante do mesmo género que a utilizada scanf.... - Significa que a função pode receber um conjunto variável de argumentos, por exemplo um ou mais apontadores de variáveis. A função retorna o número de argumentos que foram lidos com sucesso. Se chegou ao fim do ficheiro devolve o EOF, end of file. NOTA: A função fscanf com o stream = stdin é equivalente ao scanf. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 14
Ficheiros - Leitura Programa exemplo teste de leitura do ficheiro seno.txt #include <stdio.h> int main(void) { int aux; float y, x; FILE *fp; /* Abertura e teste do ficheiro */ fp = fopen ("seno.txt", "r"); if (fp == NULL) { fprintf(stdout, "Erro na abertura do ficheiro.\n"); return 0; } /* Leitura do ficheiro */ /* e' necessario saber o formato */ do { aux = fscanf (fp, "seno(%f)=%f\n", &x, &y); printf("aux = %d", aux); /*fflush(stdout);*/ /* Para forçar a escrita dos dados que estão no buffer */ getchar(); fprintf (stdout, "seno(%f)=%f\n", x, y); } while (aux == 2); Cont. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 15
Ficheiros - Leitura Programa exemplo teste de leitura do ficheiro seno.txt /* Fecha o ficheiro */ fclose(fp); fprintf(stdout, "Fim do programa n"); } return 0; Analisar o resultado do Programa. 1 - Atenção ao 2 - Atenção ao aux = -1 3 - Atenção ao fscanf Output do programa seno(0.000000)=0.000000 seno(0.174444)=0.173561 seno(0.348889)=0.341854 seno(0.523333)=0.499770 seno(0.697778)=0.642516 seno(0.872222)=0.765760 seno(1.046667)=0.865760 seno(1.221111)=0.939481 seno(1.395556)=0.984685 seno(1.570000)=1.000000 aux = -1 seno(1.570000)=1.000000 Fim do programa Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 16
Funções importantes int *fgets(char *s, int n, FILE *stream); Modo de utilização idêntico ao usado com stdin. Permite ler uma sequência de caracteres no máximo de n para um vector, a leitura termina imediatamente logo que se obtenha um \n. O carácter \n é lido e a função acrescenta o carácter terminado de string \0. A função retorna NULL quando atinge o fim de ficheiro. int getc(file *stream); Tem um funcionamento semelhante ao getchar, mas é necessário especificar o apontador do ficheiro. int *fputs(const char *s, FILE *stream); Permite escrever uma cadeia de caracteres num ficheiro. Retorna 0 se a operação teve sucesso, retorna um valor diferente de zero no caso de insucesso. int fputc(int c, FILE *stream); Escreve o caracter em c no ficheiro. Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 17
Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 18