Baixe o app para aproveitar ainda mais
Prévia do material em texto
Disciplina: Linguagem de Programação I Aula 9: Arquivos – armazenando para preservar (1ª Parte) Introdução No início, na disciplina de Lógica de Programação, aprendemos a construir programas que possibilitavam a entrada de um, ou mais dados, uma única vez. Depois, estudamos três estruturas de repetição, cada uma com suas especificidades. Nessa época, tivemos a oportunidade de desenvolver programas com grande volume de dados, mas constatamos que todos os dados não ficavam armazenados na Memória Principal e, talvez, você deva ter ficado um pouco decepcionado quando ficou provado que somente os que tinham sido digitados por último eram preservados. Alguns conceitos básicos serão apresentados para que você tenha consciência da importância do estudo sobre arquivos. Sabemos que teríamos muitas funções a serem aprendidas e a escolha de algumas foi um momento difícil. Também temos clareza de que algumas soluções ficariam muito melhores se usássemos >struct, mas como não é objeto de estudo, apresentaremos soluções bem próximas do que poderia ser ideal. Além disso, demonstraremos soluções padrão ANSI, evitando, quando possível, o uso de funções que não estão disponíveis em alguns compiladores. Objetivos Identificar vantagens e desvantagens do arquivo texto e do arquivo binário; Identificar os modos de abertura de um arquivo; Reconhecer e usar as funções fopen(), fclose(), feof(); Reconhecer e usar as funções fputc(), fgetc(), fputs(), fgets(), fprintf(), fscanf() e sscanf() para trabalhar no modo texto; Construir trechos de gravação leitura e consulta em arquivos no modo texto. Alguns conceitos Estudamos o conceito de estrutura homogênea, em que todos os elementos são do mesmo tipo, mas precisamos saber: uma estrutura heterogênea agrega dados de tipos diferentes. Em algumas linguagens, esse tipo de estrutura é chamada de registro. Nas linguagens compatíveis com a linguagem C, é denominada struct. Quando tratamos de arquivos, encontramos os seguintes conceitos: Registro Estrutura formada por vários campos (membros). Arquivo Formado por vários registros relacionados. Banco de dados Formado por vários arquivos relacionados. Sistema gerenciamento de banco de dados Conjunto de programas que gerenciam banco de dados. Operações Básicas Em primeiro lugar, quando trabalhamos com arquivo, precisamos fazer uma “ponte” entre o programa e o arquivo externo que será criado. Esse processo é, em outras palavras, a associação de uma variável ponteiro do tipo file definido na biblioteca stdio.h e o referido arquivo. Para defini-la, usamos: FILE *nomeArquivo; Atenção O asterisco, antes do nome de uma variável na declaração, significa que a variável é um ponteiro ou, de forma bem simplificada, uma variável que armazena um endereço. Abertura de um arquivo – função fopen() Essa função tem como finalidade abrir um arquivo. Caso seja possível abrir o arquivo, é retornado o endereço de uma estrutura do tipo FILE criada na MP. Caso não seja, a constante NULL será retornada, indicando o endereço 0. Veja a sintaxe dessa função: fopen("nomeDoArquivo", "modoDeAbertura"); Veja algumas considerações importantes sobre a função fopen(): O nome do arquivo pode ser representado por uma variável e, nesse caso, não terá aspas. O modo de abertura define se o arquivo será de texto ou binário. O modo de abertura informa se o arquivo está sendo aberto para leitura, gravação, leitura e gravação ou acréscimo ao final. Alguns motivos podem impedir a abertura de um arquivo: nome inválido, não existência do arquivo para um modo de abertura, não existe permissão etc. Analise o modo de abertura na tabela a seguir: Modo de abertura Breve descrição Permite leitura Permite gravação Arquivo não existente Arquivo existentePosição r Leitura Sim Não NULL OK Início w Escrita Não Sim Cria Recria Início a Acrescenta Não Sim Cria OK Fim r+ Leitura/Escrita Sim Sim Cria Permite Início 1 file:///W:/2018.2/linguagem_de_programacao_i__conv010/aula9.html alteração w+ Leitura/Escrita Sim Sim Cria Recria Início a+ Leitura/Escrita Sim Sim Cria Permite acréscimo Fim Fonte:DAMAS, L. (1951). Linguagem C. Tradução de João Araújo Ribeiro e Orlando Bernardo Filho. 10.ed. Rio de Janeiro: LTC, 2007. p. 232-233. Atenção Por default, o modo padrão é o texto logo não precisa incluir ao final de cada letra que representa o modo de abertura, a letra t. Para que possa abrir no modo binário, se faz necessário o acréscimo da letra b antes, ou depois do sinal de +. Você pode fazê-lo, por exemplo: a+b ou ab+. Escolhemos o segundo. Trecho de Abertura Dificilmente temos somente uma forma para resolver um problema e, nesse caso, não será diferente. Observe os dois trechos possíveis para se abrir um arquivo. 1ª opção variavelPonteiroArquivo=fopen("nomeArquivo", "modoAbertura"); if (variavelPonteiroArquivo==NULL) printf("\nArquivo nao pode ser aberto\n"); else { ... } 2ª opção if ((variavelPonteiroArquivo=fopen("nomeArquivo", "modoAbertura"))==NULL) printf("\nArquivo nao pode ser aberto\n"); else { ... } Fechamento de um arquivo – função fclose() Função que tem como finalidade fechar o arquivo, embora todos os arquivos sejam fechados quando o programa é finalizado, não devemos deixar de usá-la para evitar que alguns tipos de problemas possam danificar o arquivo durante o fechamento automático. Se o fechamento for bem sucedido, retorna 0. Caso contrário, retorna EOF, por definição –1 no Windows e Linux. Você lerá sobre EOF mais adiante. Veja a sintaxe da função: 2 file:///W:/2018.2/linguagem_de_programacao_i__conv010/aula9.html fclose(nomeVariavelPonteiroArquivo); Agora, veja um exemplo de aplicação da função fclose(): If(fclose(variavelPonteiroArquivo)==0) printf("\nArquivo fechado com sucesso\n"); else { printf("\nSurgiu algum problema\n"); } Saiba mais Normalmente, não construímos trechos de proteção para verificar se o arquivo foi fechado com sucesso, mas será apresentado para que saiba como fazê-lo se precisar, em algum momento. Fim do arquivo – função feof() Essa função “detecta” o fim de um arquivo. Como não tem nenhuma restrição, a função feof() é usada em arquivos textos, também. Atenção Não confunda a função feof() com a constante End-of-File (EOF) que “marca” o fim do arquivo e que, algumas vezes, é definida como sendo um caracter. Por definição, como já vimos, a constante EOF é o valor numérico -1 para muitos compiladores. Veja a sintaxe da função: feof(variavelPonteiroArquivo); Observe como combinamos essa função com uma estrutura de repetição. Essa combinação pode compor um trecho de leitura de um arquivo. while(!feof(variavelPonteiroArquivo)) { ... } É necessário ter um cuidado especial ao usar a função feof() quando for contar caracteres de um arquivo, pois o resultado será acrescido de, pelo menos, um na contagem. Criando arquivo Essa função “detecta” o fim de um arquivo. Como não tem nenhuma restrição, a função feof() é usada em arquivos textos, também. O programador da Linguagem C tem a liberdade de impor a estrutura que deseja de acordo com suas necessidades ao criar um arquivo. Temos clareza de que a escolha ideal da estrutura é fundamental para as operações que serão realizadas com o arquivo, mas, não existe uma imposição por parte da linguagem. Afirmamos isso porque, em alguns exemplos, tudo poderia ser mais simples se tivesse usado uma estrutura do tipo struct, mas isso não impediu que o arquivo fosse criado com as estruturas que estudamos. Nós iremos trabalhar com o arquivo no modo texto e arquivo no modo binário. Comentário Nesta aula, estudaremos o modo texto e esperamos que se sinta muito à vontade de acrescentar trechos de proteção estudados em aulas anteriores e transformar trechos em funções. Iremos agora, estudar algumas funções para que possamos começar a construir nossos arquivos que poderão ter operações do tipo: Criar arquivo Incluir dados Consultar Alterar Excluir Funções fputc() Essa função possibilita a gravação de um caracter em um arquivo. Sintaxe: fputc(nomeVariavel, varPonteiroArquivo); fgetc() Essa função possibilita a leitura de um caracter de um arquivo. Sintaxe: fgetc(varPonteiroArquivo); Veremos a seguir uma aplicação na qual caracteres serão lidos do teclado e armazenados em um arquivo e, depois, lidos do arquivo e exibidos no display. Dessa forma, faremos uso das funções fputc() e fgetc(), respectivamente. Essas ações serão realizadas através de dois programas. Como será o primeiro programa com arquivos, detalharemos o necessário para um bom entendimento. 1 Começaremos com a declaração da variável ponteiro de arquivo que servirá para os dois programas. FILE *arq; 2 O próximo é o trecho de abertura do arquivo de gravação. if((arq = fopen(“texto.txt”, “a”)) == null) printf(“\nArquivo NÃO pode ser aberto \n”); else { ... } O nome do arquivo externo é texto.txt e o modo de abertura escolhido foi a, significando que a opção foi para o modo texto e aberto só para acrescentar ao final. 3 Agora, será apresentado o trecho de abertura para leitura, usando a variável declarada e um teste para verificar se o arquivo foi ou não aberto. if((arq = fopen(“texto.txt”, “r”)) == null) printf(“\nArquivo NÃO pode ser aberto \n”); else { ... } O nome do arquivo externo é texto.txt e o modo de abertura escolhido foi r, significando que a opção foi para o modo texto e somente para leitura. O próximo passo será o de gravação no arquivo. Observe que usaremos stdin como argumento da função. Pode parecer estranho considerar dispositivos como arquivos, mas, como os programas dialogam com os arquivos por meio de um canal de comunicação, é bem razoável aceitar essa ideia. É possível observar isso na entrada de dados, quando estes fluem pelo teclado, quando qualquer informação aparece na tela ou, ainda, quando abrimos um arquivo do tipo .doc. Em algum momento, você já deve ter lido uma mensagem exibida pelo Word informando que o arquivo está “aberto apenas para leitura”, quando tentamos abri-lo novamente. Para facilitar a programação na Linguagem C, alguns arquivos, classificados como padrão, são abertos, automaticamente, no início da execução de um programa, e três deles já foram vistos por nós, mesmo sem conhecermos esse conceito. São eles: stdin Entrada padrão stdout Saída padrão stderr Local que exibe as mensagens de erro Comentário Algumas funções que estudaremos aqui poderão ter como argumentos esses arquivos. Para tentar esclarecer esse conceito, apresentaremos um exemplo de funções: ao trocar a origem ou o destino, em vez de ler ou gravar de/em um arquivo em disco, desviamos o fluxo para o teclado (stdin) ou para o vídeo (stdout). As funções serão vistas mais adiante, porém, pela semelhança com as funções que já estudamos, será fácil entendê-las. O código Vamos analisar o código a seguir. #include<stdio.h< #include<stdlib.h< int main() { int num; fputs(“\ncom fputs-numero: “, stdout); fscanf(stdin, “%d”,&num); fprintf(stdout, "\nLido com fscanf"); fprintf(stdout, “e exibido com fprintf: %d“, num*5); printf("\n\n"); system(“pause”); } A função fputs() é semelhante a função puts(); fscanf() é semelhante a scanf() e fprintf() é semelhante a printf(). Duas funções gravam em arquivo e a terceira, lê do arquivo. Entretanto, ao usar stdin ou stdout, desviamos para a entrada padrão ou para saída padrão. Depois dessa pequena explanação sobre alguns arquivos padrão, voltaremos aos trechos do programa em questão. Trecho de gravação: caracter = getchar() while (!feof(stdin)) { fputc(caracter, arq); caracter = getchar(); } A função getchar() foi estudada nas primeiras aulas e espera que o usuário pressione uma tecla. Qualquer dúvida retorne para relembrar. O uso do stdin se justifica, porque o fim do arquivo será detectado quando o usuário digitar CTRL F (Windows) ou CTRL D (Linux) logo depois que a tecla enter tiver sido pressionada. Trecho de leitura do arquivo: caracter = fgetc() while (!feof(sarq)) { putchar(caracter); caracter = fgetc(arq); } Saiba mais Veja os dois programas completos <galeria/aula9/anexo/a09_doc01.pdf> . Arquivo txt file:///W:/2018.2/linguagem_de_programacao_i__conv010/galeria/aula9/anexo/a09_doc01.pdf Você pode digitar várias frases em um arquivo novo aberto no bloco de notas e salvá- lo com o nome que desejar. Não é obrigatório usar a extensão .txt, mas é um bom hábito. Coloque o nome no lugar dos XXXXX e, depois, compile o arquivo lerTexto.c e execute-o. if((arq = fopen(“XXXXX.txt”, “r”)) == NULL) Você constatará que a gravação resultou em um arquivo texto comum. Saiba mais Para finalizarmos essa parte, veja um programa que funciona por meio de um menu <galeria/aula9/anexo/a09_doc02.pdf> , tendo como opções esses dois programas, mas sob a forma de funções do tipo void e sem parâmetros.. Funções fputs() e fgets() fputs() Essa função possibilita a gravação de uma linha em um arquivo. Sintaxe: fputs(vetorChar, varPonteiroArquivo); fgets() Essa função possibilita a leitura de uma linha de um arquivo. Sintaxe: file:///W:/2018.2/linguagem_de_programacao_i__conv010/galeria/aula9/anexo/a09_doc02.pdf fgets(nomeVariavel, tamanho, varPonteiroArquivo); Você já teve oportunidade de usá-la com stdin para ler um vetor de char. Como o nome do vetor de char é um endereço, não faz parte da sintaxe o '&' que, precedendo o nome da variável, significa endereço. Comentário Incluímos uma função da biblioteca string.h(strlen) e uma da biblioteca ctype.h(toupper). Após ler os outros exemplos, sugerimos que construa o trecho de gravação para esse exemplo. Em nosso exemplo, criamos o seguinte arquivo no bloco de notas. Nome: fgets.txt O arquivo foi aberto pelo trecho a seguir. Observe o modo de abertura, r, significando que será somente de leitura e é um arquivo texto. arq = fopen(“fgets.txt”,”r”); if (arq == null) printf(“\nArquivo NÃO pode ser aberto\n”); No trecho de leitura, incluímos uma variável para contar o número de linhas do arquivo. No arquivo criado no bloco de notas, colocamos nomes de pessoas com letras minúsculas e maiúsculas, mas, na saída, todas as letras são convertidas para maiúsculas. contalinha = 1; while(!feof(arq)) { fgets(linha, 80, arq); /*voce pode usar a funcao strupr se estiver disponivel no compilador*/ for(x = 0; x < strlen(linha; x++) linha[x] = toupper(linha[x]); printf(“linha %d : %s\n”, contalinha, linha); contalinha++; } Agora, veja a saída: Nesse segundo exemplo, apresentaremos dois programas: um que lê do teclado e grava no arquivo e outro que lê do arquivo e exibe na tela. Perceba que poderíamos ter deixado de fazer o trecho de gravação e gerado o arquivo no bloco de notas. Sabemos que é mais simples, uma vez que a alteração em arquivos textos é bem complicada no que diz respeito à sobreposição de dados que poderá acontecer. Sendo assim, preferimos fazer os trechos de gravação e leitura separados e deixar para editar no bloco de notas somente no caso de alteração. Saiba mais Analise o código <galeria/aula9/anexo/a09_doc03 .pdf> para ler. Atividade 1. Crie um código para armazenar em linhas de texto, nome e idade. Funções fprintf() e fscanf() Agora, vamos analisar outras funções muito importantes: fprintf() Semelhante à função printf(), mas tem um argumento a mais que é o ponteiro de arquivo. Com vimos em exemplo anterior, esse ponteiro pode ser substituído por stdin. Sintaxe: fprintf(varPonteiroArquivo, “%...%...%...”, variáveis); fscanf() file:///W:/2018.2/linguagem_de_programacao_i__conv010/galeria/aula9/anexo/a09_doc03.pdf Semelhante à função scanf(), mas tem um argumento a mais que é o ponteiro de arquivo. Sintaxe: fscanf(varPonteiroArquivo, “%...%...%...”, endereços); sscanf() Essa função é muito parecida com scanf(). A única diferença é que scanf() lê do teclado e ela lêuma string (vetor de char). Sendo assim, dados numéricos poderão ser lidos de um arquivo para uma string, isto é, usando a função fgets() e, depois, “extraídos” da string lida por sscanf(), resolvendo o problema gerado na alternância de fegts() com fscanf().Sintaxe: sscanf(string, “%...%...%...”, endereços); Evite alternar uso de fgets() com fscanf(), pois, como já estudamos com fgtes() e scanf(), existe um problema de buffer. Sugerimos a leitura sempre com fgets() e o uso da função sscanf. ] Atividade 2. Construa um programa que leia matrícula e duas notas, enquanto tiver dados no arquivo e exiba a matrícula, as duas notas e a média. Notas NULL A constante NULL é escrita com letras maiúsculas. Problemas Entre alguns, podemos citar: falta de energia, falha do SO etc. Referências DA MATTA, Roberto. Uma introdução à antropologia social. Rio de Janeiro: Rocco, 1993. DURHAM, Eunice. “Apresentação”. In: MALINOWSKI, Bronislaw. Argonautas do pacífico ocidental: um relato do empreendimento e da aventura dos nativos nos arquipélagos de Nova Guiné Melanésia. São Paulo: Abril Cultura, 1978. LAPLANTINE, François. Aprender antropologia. São Paulo: Brasiliense, 2006. MALINOWSKI, Bronislaw. Argonautas do pacífico ocidental: um relato do empreendimento e da aventura dos nativos nos arquipélagos de Nova Guiné Melanésia. São Paulo: Abril Cultura, 1978. KUPER, Adam. Antropólogos e Antropologia. Rio de Janeiro: Francisco Alves, 1978. VELHO, Gilberto. “Observando o familiar”. In: NUNES, Edson de Oliveira. A aventura sociológica. Rio de Janeiro: Zahar, 1978. Próximos Passos Arquivo no modo binário e a funções para trabalhar com ele; Conceito de arquivo binário; Funções rewind(), fread(), fwrite(), fgetpos(), fsetpos(), fseek(), ftell(), rename(), remove(), rewind(); Trechos de gravação leitura, consulta, alteração e exclusão em arquivos no modo binário. Explore mais Para saber mais sobre os assuntos dessa aula, veja os últimos exemplos <galeria/aula9/anexo/a09_doc06.pdf> que separamos para seus estudos. 1 2 file:///W:/2018.2/linguagem_de_programacao_i__conv010/galeria/aula9/anexo/a09_doc06.pdf
Compartilhar