Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: 030714_01 Arquivos Arquivos Tipos de arquivo: Sequencial (texto) Caracteres armazenadas sequencialmente. É possível determinar o primeiro, segundo terceiro .. caracteres que compõem o arquivo Binário Formado por uma sequência de bytes sem correspondência com um tipo de dado. Cabe ao programador fazer esta correspondência quando lê e escreve estes arquivos. Como trabalhar com arquivos Antes de acessar os dados dentro de um arquivo é necessário abri-lo. Executa-se as operações desejadas com o arquivos usando funções específicas para leitura e escrita Ao terminar de realizar as operações no arquivo, devemos fechá-lo. As operações de abertura e fechamento garantem a integridade dos dados. As funções referentes a arquivos requerem a inclusão do stdio.h, e todo arquivo aberto é referenciado por um ponteiro para o tipo FILE. Descritor de Arquivos Descritor de arquivo: Em C: Estrutura de dados denominada FILE Memória Disco Arquivo “Físico” Descritor de Arquivo (FILE) Arquivo “lógico” em memória Aponta para um arquivo físico no disco O arquivo lógico e armazenado em variáveis de memória definidas pelo programador. Todas operações feitas pelo descritor refletem no arquivo Criando um descritor: FILE *parquivo; Abrindo arquivos A função “fopen” tem duas finalidades: - abrir uma descritor de bytes - ligar um arquivo em disco àquele descritor FILE *fopen(char *NomeArquivo, char *modo); FILE *arquivo; if ((arquivo = fopen(“teste”,”w”)) == NULL) { puts(“Não posso abrir o Arquivo teste.\n”); exit(1); /* força o término da execução da rotina */ } Abrindo arquivos Outro exemplo FILE *parquivo; char *nome = "texto.txt"; if (( parquivo = fopen(nome, "w+b")) == NULL) { printf("\n\nNao foi possivel abrir o arquivo para escrita.\n"); exit(1); } Modo Significado “r” Abre Arquivo de Texto para Leitura “w” Cria Arquivo de Texto para Gravação “a” Anexa a um Arquivo de Texto “rb” Abre Arquivo Binário para Leitura “wb” Cria Arquivo Binário para Gravação “ab” Anexa a um Arquivo Binário “r+” Abre Arquivo de Texto para Leitura/Gravação “w+” Cria Arquivo de Texto para Leitura/Gravação “a+” Abre ou Cria Arquivo de Texto para Leitura/Gravação “r+b” Abre Arquivo Binário para Leitura/Gravação “w+b” Cria Arquivo Binário para Leitura/Gravação “a+b” Abre ou Cria Arquivo Binário para Leitura/Gravação Fechando arquivo Fechando um arquivo: função fclose(..) Quando um programa não precisa mais utilizar um arquivo por um período de tempo longo, o arquivo pode ser fechado Fechar um arquivo protege os seus dados, garante que atualizações feitas serão salvas e libera o arquivo para outros usuários ou programas poderem utiliza-lo. int fclose(FILE *fp); fclose(arquivo); Leitura de dados C provê funções para ler caracteres, linhas de texto, padrões formatados ou vetores de bytes: int getc(FILE *arquivo); lê um caracter do arquivo e retorna seu valor como inteiro. Retorna EOF em caso de erro int fgetc(FILE *f) lê um byte, retorna seu valor (0-255) como inteiro. Retorna EOF em caso de erro. char *fgets(char *dest, int limite, FILE *f); lê uma linha de texto (ou até atingir o limite de bytes lidos) e guarda o texto lido em dest. Retorna dest em caso de sucesso, NULL em caso de erro. int fscanf(FILE *f, char *formato, ...); scanf para arquivos. int fread(void *dados, int tam_elem, int num_elem, FILE *f); lê num_elem elementos de tam_elem bytes cada e armazena em dados. Retorna o número de elementos lidos com sucesso. #include <stdio.h> #include <conio.h> int main() { FILE * fp; char ch; fp = fopen ("arquivo.txt" , "r"); if (fp == NULL) perror ("Erro abrindo arquivo"); else { ch = getc(fp); while (ch != EOF){ ch = getc(fp); putchar (ch); } fclose (fp); } return 0; } Exemplo de código para ler e imprimir usando getc #include <stdio.h> int main() { FILE * pFile; char mystring [100]; pFile = fopen (“arquivo.txt" , "r"); if (pFile == NULL) perror ("Erro abrindo arquivo"); else { fgets (mystring , 100 , pFile); puts (mystring); fclose (pFile); } return 0; } Exemplo de código para ler e imprimir usando fgets Escrita de dados C provê funções para escrever caracteres, strings, padrões formatados ou vetores de bytes: int putc(int c, FILE *f) Escreve o caracter c. Retorna EOF em caso de erro. int fputc(int c, FILE *f) Escreve o byte c. Retorna EOF em caso de erro. int fputs(char *dest, FILE *f); Escreve a string dest (que deve ter o zero terminador) no arquivo. Retorna EOF em caso de erro. int fprintf(FILE *f, char *formato, ...); printf para arquivos. int fwrite(void *dados, int tam_elem, int num_elem, FILE *f); Escreve num_elem elementos de tam_elem bytes cada, armazenados em dados. Retorna o número de elementos escritos com sucesso. main(){ FILE *arq; char ch; if ((arq=fopen(“teste.dat”,”w”)) == NULL) { printf(“Arquivo não pode ser criado\n”); exit(1); } do{ ch=getchar(); putc(ch,arq); }while (ch!=0); fclose(arq); } Escreve cada caracter lido em um arquivo usando putc #include <stdio.h> int main () { FILE * pFile; char str [256]; printf (“Informe string a gravar em arquivo: "); fgets (str,255,stdin); pFile = fopen (“arquivo.txt","a"); fputs (str, pFile); fclose (pFile); return 0; } Escreve uma string lida em um arquivo usando fputs fwrite ( ) e fread ( ) Permitem escrever e ler blocos de dados, sua forma geral é a seguinte: int fread(void *buffer, int num_bytes, int cont, FILE *fp); int fwrite(void *buffer, int num_bytes, int cont, FILE *fp); #include <stdio.h> int main() { FILE *pf; float pi = 3.1415; float pilido; if((pf = fopen("arquivo.bin", "wb")) == NULL) { printf("Erro na abertura do arquivo"); exit(1); } if(fwrite(&pi, sizeof(float), 1,pf) != 1) /* Escreve a variável pi */ printf("Erro na escrita do arquivo"); fclose(pf); /* Fecha o arquivo */ if((pf = fopen("arquivo.bin", "rb")) == NULL){ /* Abre o arquivo para nova leitura */ printf("Erro na abertura do arquivo"); exit(1); } if(fread(&pilido, sizeof(float), 1,pf) != 1) /* Le em pilido o valor da variável armazenada anteriormente */ printf("Erro na leitura do arquivo"); printf("\nO valor de PI, lido do arquivo e': %f", pilido); fclose(pf); return(0); } Exemplo usando fwrite e fread Erros com arquivos A função ferror() determina se a operação de arquivo produziu um erro. Sua forma geral será: int ferror(FILE *fp); #include <stdio.h> int main () { FILE * pFile; pFile=fopen(“arquivo.txt","r"); if (pFile==NULL) perror ("Erro ao abrir arquivo"); else { fputc ('x',pFile); if (ferror (pFile)) printf ("Erro na escrita ao arquivo\n"); fclose (pFile); } return 0; } Posicionamento do cursor Em todo arquivo aberto há um "cursor" indicando a posição onde ocorrerá a próxima leitura e/ou escrita. Todas as operações de leitura e escrita avançam o cursor após ler/escrever os dados. Para mover o cursor, ou obter sua posição atual, temos: int fseek(FILE *f, long distancia, int origem); Move o cursor do arquivo f para a posição distancia relativa em bytes a alguma origem. A origem deve ser uma destas 3 constantes: SEEK_SET – início do arquivo SEEK_CUR – posição atual SEEK_END – fim do arquivo fseek retorna 0 em caso de sucesso, -1 em caso de erro. Obs: Normalmente é utilizado em arquivos binários long rewind(FILE *f); Move o cursor para o inicio do arquivo. long ftell(FILE *f); Retorna a posição atual do cursor no arquivo f. main(){ FILE *fp; char c; if ((fp=fopen(“teste”,”rb”)) == NULL) { printf(“Arquivo não pode ser aberto\n”); exit(1); } fseek(fp,234L,0); c = getc(fp); /* L força que seja um inteiro longo */ /* lê o caracter 234 */ putchar(c); } Lê um caracter do arquivo binário Obter o tamanho de um arquivo int main () { FILE * pFile; long lSize; pFile = fopen ( "myfile.bin" , "rb" ); if (pFile==NULL) { fputs ("File error",stderr); exit (1); } fseek (pFile , 0 , SEEK_END); /* vai para fim do arquivo */ lSize = ftell (pFile); /* retorna posicao atual */ rewind (pFile); /* volta para inicio */ printf(“Tamanho do arquivo em bytes%lf”, lSize); } Programa para copiar arquivos #include “stdio.h” int main(int argc,char *argv[]) { FILE *in, *out; char ch; if (arg != 3) { printf(“Digite o Nome dos Arquivos\n”); exit(1); } if ((in=fopen(argv[1],”rb”)) == NULL) { printf(“Arquivo origem não existe\n”); exit(1); } if ((out=fopen(argv[2],”wb”)) == NULL) { printf(“Arquivo destino não existe\n”); exit(1); } while (! feof(in)) putc(getc(in),out); /* esta é a cópia propriamente dita */ fclose(in); fclose(out); }