Manipulando Arquivos
Teoria
Introdução
Fala aí, aqui é o Guga do Responde Aí! Tudo bem com você?
Nós já sabemos como criar arquivos na linguagem C, mas como podemos ler ou adicionarmos mais informações nele através de um programa?
A resposta é bem simples, existem duas funções principais tanto para lermos quanto para escrevermos dados em um arquivo e hoje nós vamos conversar um pouco sobre elas.
Vem monstro!
Lendo dados de um arquivo
Imagine que nós temos um programa em que o usuário pode personalizar as configurações da maneira que ele preferir. Para que isso aconteça, o método que nós utilizamos para salvar essas configurações foi utilizar um arquivo que é carregado toda vez que o programa é iniciado para ser lido por ele.
Molezinha até agora, né? Para facilitar, vamos também imaginar que só existem as seguintes duas configurações para serem alteradas: tema e mostrar informações pessoais.
Com base nisso, temos o seguinte arquivo com a configuração do programa preferida de um suposto usuário:
Onde o tema do programa deve ser o escuro e a exibição das informações pessoais desse suposto usuário devem ser desabilitadas.
Sendo assim, como codificaríamos o nosso programa para ler esses dados e executar os comandos necessários de configuração?
Beleza, muita calma nessa hora!
Começando pelas declarações, para fazer isso nós iríamos precisar de uma string responsável por armazenar uma configuração lida do arquivo e de uma variável contadora de linhas desse arquivo.
Declarando tudo isso teríamos algo mais ou menos assim:
Após isso, nós também teríamos que abrir o nosso arquivo de configurações no modo de leitura, mas isso nós já sabemos fazer:
Com o arquivo aberto, nós podemos ler os dados armazenados nele da seguinte forma:
Onde nós utilizamos um laço de repetição while para criar dois loops com a variável contadora (já que sabemos que o arquivo se limita a duas linhas de configurações por conta de sua formatação configuração/linha) e utilizamos a função fscanf para ler a configuração de determinada linha e armazená-la na string do nosso programa.
Com licença, MAS QUE RAIOS DE FUNÇÃO É ESSA?
Vamos lá, a função fscanf é similar a função que nós já conhecemos chamada scanf, a grande diferença é que ao invés de armazenar uma entrada do teclado em uma variável ela lê essa entrada de um arquivo.
Para ficar fácil, mas muito fácil mesmo, vamos entendê-la de maneira geral:
Como conseguimos observar se trata de uma função que espera três parâmetros, o primeiro deles é o ponteiro para o arquivo que estamos trabalhando (no nosso exemplo é o ponteiro ), o segundo parâmetro é o especificador do tipo do dado que será lido do arquivo, no nosso caso utilizaremos o especificador “%s”, pois estaremos lendo strings (funciona também para os outros especificadores, exatamente da mesma maneira que a função scanf). O último parâmetro, por sua vez, é equivalente a variável que armazenará o dado lido do arquivo em nosso programa, no nosso caso estamos utilizando a string para armazenar as strings que serão lidas do arquivo.
Basicamente é isso, com essa simples linha de código nós iremos conseguir ler as configurações pessoais do suposto usuário no nosso programa fictício.
Mas não se iluda, devemos nos atentar que ao invés de apenas imprimirmos essa configuração (como fizemos na linha 11 da imagem exemplo após a abertura do arquivo), nós iríamos programar os comandos para que, nesse caso, o tema escuro do programa fosse aplicado e que as informações pessoais desse usuário fossem ocultadas (já que são as duas configurações que seriam lidas do arquivo exemplo).
Para finalizar, não podemos nos esquecer de fechar o arquivo que foi aberto para leitura após terminarmos as manipulações com ele:
Escrevendo dados em um arquivo
Agora nós já sabemos ler dados de um arquivo, mas como podemos escrever dados nele?
Simples! A estrutura é basicamente a mesma, começando pelas declarações teríamos algo mais ou menos assim:
Uma string chamada responsável por armazenar o conteúdo que será escrito no arquivo.
Em seguida, diferente do exemplo anterior, nós vamos criar um arquivo de texto chamado no modo de escrita (pode ser um arquivo existente desde que o mesmo seja aberto no modo de escrita):
Sendo assim, a grande diferença em relação a leitura de dados é que ao invés de utilizarmos a função fscanf, quando queremos escrever um dado em um arquivo nós devemos utilizar a função fprintf da seguinte forma:
Onde a única coisa que muda em relação a função fscanf é que o segundo parâmetro se refere ao especificador de tipo do dado que será escrito e o terceiro parâmetro a variável que contém esse dado.
Para finalizarmos a escrita basta fecharmos o arquivo:
Agora que já entendemos alguns dos conceitos de manipulações de arquivos, que tal resolvermos alguns exercícios de fixação?
Escrevendo dados em um arquivo
Exercícios Resolvidos
Exercício Resolvido #1
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 01.
Faça um programa que crie/abra um arquivo de texto denominado “arq.txt” e permita que o usuário grave diversos caracteres nesse arquivo até que o mesmo entre com o caractere “0”. Por fim, o arquivo deve ser fechado.
Passo 1
Belezinha, vamos começar fazendo aquilo que nós já sabemos, que é definir o escopo do nosso programa principal, as variáveis que iremos utilizar e abrir o arquivo que iremos manipular:
Passo 2
Prontinho, agora que já temos o arquivo “arq.txt” aberto, devemos permitir que o usuário insira quantos caracteres ele desejar nesse arquivo até que o caractere “0” seja inserido.
Um laço de repetição cai muito bem nesse caso:
Mais precisamente uma estrutura while com condição 1 (sempre verdadeira) que irá requisitar a entrada de um caractere ao usuário e verificar se esse caractere é igual a “0”. Caso seja, o comando break é executado e a execução da estrutura de repetição é encerrada, caso contrário, o caractere inserido é gravado no arquivo “arq.txt” e um novo loop é iniciado.
Passo 3
Por fim, não podemos nos esquecer de fechar o arquivo:
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #2
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 02.
Faça um programa que abra um arquivo de texto e mostre quantas linhas esse arquivo possui.
Passo 1
Para resolvermos esse exercício devemos primeiro ter o seguinte conceito na cabeça: um arquivo texto sempre terá uma linha (mesmo que ela esteja em branco).
Olha ela aqui:
A partir disso, podemos descobrir quantas linhas um arquivo têm contando quantos operadores especiais de quebra de linha (%n) esse arquivo possui adicionando 1 linha no final dessa conta.
Passo 2
Tendo isso em mente, vamos começar definindo o escopo do nosso programa principal, as variáveis que iremos utilizar e abrir o arquivo que iremos manipular:
Passo 3
Pronto, agora que nós já temos o arquivo aberto, basta utilizarmos uma estrutura de repetição para percorrermos cada um dos caracteres do mesmo:
Observe que na condição da estrutura while, utilizamos a função fscanf para obter cada caractere presente nesse arquivo desde que o seu retorno não seja EOF (End Of File ou fim do arquivo).
Ou seja, se o retorno da função fscanf for um caractere do arquivo, nós verificaremos se esse caractere é o \n. Caso seja, incrementamos a variável em uma unidade (pois se trata de um quebra de linha), caso contrário, o programa irá prosseguir para o próximo loop até que todos os caracteres tenham sido verificados e o EOF seja retornado.
Passo 4
Por fim, basta fecharmos o arquivo e imprimirmos a variável :
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #3
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 03.
Faça um programa que abra um arquivo de texto e mostre na tela quantos caracteres desse arquivo são vogais.
Passo 1
Começaremos o nosso programa definindo o escopo do nosso código principal, as variáveis que iremos utilizar e abrindo o arquivo que iremos manipular:
Passo 2
Com o arquivo aberto, basta utilizarmos uma estrutura de repetição para percorrermos cada um dos caracteres presentes no mesmo:
Onde, a cada caractere obtido através da função fscanf, verificaremos através do comando condicional if se o mesmo se trata ou não de uma vogal. Caso seja, a variável será incrementada em uma unidade, caso contrário, o laço de repetição apenas continuará os seus loops até que o EOF (fim do arquivo) seja retornado pela função fscanf.
Passo 3
Por fim, basta fecharmos o arquivo e imprimirmos a variável :
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #4
Elaboração própria.
Faça um programa que receba um título e um texto, ambos inseridos pelo usuário, crie um arquivo que tenha como nome o título e grave nesse arquivo o texto.
Passo 1
Começaremos o nosso programa definindo o escopo do nosso código principal e as variáveis que iremos utilizar:
Passo 2
Agora que já temos as variáveis necessárias para o funcionamento do nosso programa, podemos requisitar ao usuário a entrada do título do arquivo e do texto que será gravado nele:
Em seguida, utilizamos o título inserido como parâmetro da função fopen para que o arquivo seja criado e aberto para manipulação.
Passo 3
Com o arquivo pronto para uso, podemos utilizar a função fprintf para gravarmos as informações que estão armazenadas na string :
Para isso, devemos passar como primeiro parâmetro da função fprintf o ponteiro do arquivo, que nesse caso é , como segundo parâmetro, o especificador de tipo do que será gravado no arquivo, como iremos gravar uma string esse especificador é o %s. Por fim, como terceiro e último parâmetro da função fprintf, devemos passar a variável que armazena o conteúdo que será gravado no arquivo, nesse caso a string
Prontinho, agora só precisamos utilizar a função fclose para fecharmos o arquivo!
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #5
Elaboração própria.
Faça um programa que receba o título de um arquivo, abra esse arquivo e utilize a função fscanf para imprimir o conteúdo do mesmo.
Passo 1
Começaremos o nosso programa definindo o escopo do nosso código principal e as variáveis que iremos utilizar:
Passo 2
Agora que já temos tudo aquilo que será necessário para o funcionamento do programa, podemos requisitar ao usuário o título do arquivo:
Em seguida, utilizamos o título inserido como parâmetro da função fopen para que o arquivo seja aberto no modo de leitura (para isso o arquivo deve existir).
Passo 3
Com o arquivo aberto, podemos utilizar uma estrutura de repetição para percorrer e imprimir cada caractere presente nesse arquivo:
Faremos isso utilizando a função fscanf como condição de um laço de repetição while. Ou seja, enquanto a função fscanf for diferente de EOF (End Of File ou fim do arquivo), nós iremos imprimir o caractere retornado por ela.
Para isso, devemos codificar a função fscanf passando como primeiro parâmetro o ponteiro do arquivo que será lido, nesse caso , como segundo parâmetro o especificador de tipo do que será lido, nesse caso %c já que iremos ler caractere por caractere. Por fim, como terceiro e último parâmetro, devemos passar a variável que irá armazenar aquilo que será lido do arquivo, nesse caso a variável do tipo char (assim como a função scanf, devemos colocar o &).
Passo 4
Com o arquivo já impresso na tela, não podemos nos esquecer de fechar esse mesmo arquivo antes de encerrarmos o programa:
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #6
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 14.
Faça um programa que requisite o ano atual ao usuário, abra um arquivo chamado “arq.txt” que contém um conjunto de registros formados por nomes e datas de nascimento, por exemplo:
E seja capaz de imprimir na tela o nome e a idade que essa pessoa terá ou têm nesse ano. Todas as impressões devem ser feitas no final do programa, ou seja, as informações de nome e idade devem ser armazenadas.
Passo 1
Como nós temos que realizar a impressão do nome e da idade de todas as pessoas do arquivo, começaremos o nosso programa criando uma estrutura que representará esse pessoa no programa:
Observe que a biblioteca string foi inclusa, uma vez que iremos trabalhar com strings nesse programa.
Passo 2
Após termos criado a nossa estrutura, podemos declarar todas as variáveis que nós utilizaremos:
Passo 3
Com as variáveis essenciais declaradas, iremos agora requisitar a entrada do ano atual ao usuário e abrir o arquivo “arq.txt” no modo de leitura:
Passo 4
Com o arquivo aberto, utilizaremos como condição de um laço de repetição a função fscanf para obter cada linha do arquivo enquanto EOF não for retornado:
Vale ressaltar que antes de novos loops do laço de repetição serem executados, as informações lidas do arquivo são repassadas para o vetor de estruturas do tipo que nós criamos na etapa de declaração das variáveis essenciais. Isso fará que mesmo que as variáveis presentes na função fscanf sejam substituídas por outros valores as informações passadas continuem sendo armazenadas para serem impressas no final do programa.
Ou seja, a cada loop a variável é copiada através da função strcpy da biblioteca string para o campo do índice do vetor de estruturas do tipo chamado . O mesmo acontece com a idade, que é obtida através da subtração do ano atual pelo ano de nascimento daquele registro e armazenado no campo da mesma estrutura.
Passo 5
Por fim, basta imprimirmos o nome e a idade dos registros presentes no arquivo acessando ao final do programa os campos e de cada índice do vetor de estruturas do tipo :
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #7
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 09.
Faça um programa que receba dois arquivos do usuário e crie um terceiro arquivo com o conteúdo dos dois primeiros juntos (o conteúdo do primeiro seguido do conteúdo do segundo).
Passo 1
Vamos começar esse programa declarando tudo aquilo que será essencial para o seu funcionamento:
Passo 2
Com todas as variáveis declaradas, podemos requisitar ao usuário o nome dos dois arquivos que terão os seus respectivos conteúdo copiados para um terceiro arquivo:
Passo 3
Tendo o nome dos dois arquivos, podemos começar abrindo o primeiro arquivo no modo de leitura e o resultante das duas cópias:
Em seguida, basta utilizarmos a função fscanf para copiarmos cada caractere do primeiro arquivo e, em seguida, gravá-los no terceiro arquivo utilizando a função fprintf.
Passo 4
Com o primeiro arquivo copiado, podemos fechá-lo e abrir agora o segundo arquivo no modo de leitura:
Passo 5
Assim como antes, basta utilizarmos a função fscanf para copiarmos cada caractere do segundo arquivo e, em seguida, gravá-los no terceiro arquivo utilizando a função fprintf:
Passo 6
Por fim, após termos copiado os dois arquivos inseridos pelo usuário e gerado um terceiro com o conteúdo deles, basta fecharmos os arquivos que estavam abertos antes de encerrarmos o programa:
Resposta
Ei, a resposta está no passo a passo :)
Exercício Resolvido #8
Universidade Federal de Uberlândia – UFU, Lista de exercícios de programação em C: Arquivos, André Backes, 2015, pp. 01 – Adaptação do exercício 17.
Faça um programa que leia um arquivo que contenha as dimensões de uma matriz (linha e coluna), a quantidade de posições que serão anuladas e as posições a serem anuladas. Em seguida, imprima na tela uma matriz com essas dimensões onde as posições não-nulas são preenchidas com 1 e as nulas com 0.
Exemplo de arquivo de entrada:
Matriz resultante:
Passo 1
Bom, nós já somos craques nisso, então... Vamos começar o nosso programa declarando as variáveis essenciais para o funcionamento dele:
Passo 2
Com todas essas variáveis declaradas, nós agora podemos abrir o arquivo que armazena as informações de nossa matriz no modo de leitura:
Passo 3
Beleza! Vamos agora analisar o arquivo exemplo mais uma vez:
Você percebe a importância da primeira linha desse arquivo?
Ela basicamente passa as informações gerais da nossa matriz: número de linhas, número de colunas e quantas posições deverão ser anuladas.
É justamente por esse motivo que antes de continuarmos nós iremos utilizar a função fscanf para ler do arquivo as informações gerais da matriz e armazená-las em variáveis do nosso programa:
Passo 4
Agora que finalmente temos informações relevantes sobre a matriz que iremos imprimir (lidas da primeira linha do arquivo), podemos finalmente declará-la com as dimensões corretas e preenchê-la com o valor 1:
Passo 5
Agora que temos uma matriz devidamente preenchida, está na hora de utilizarmos um laço de repetição para percorrermos o arquivo verificando quais posições de devem ser anuladas:
Ou seja, utilizaremos a função fscanf a cada loop do laço de repetição for para ler do arquivo qual posição deve ser anuladas ( e ) e, logo em seguida, atribuímos o valor 0 a essa posição de .
Isso deve se repetir até que todas as anulações tenham sido feitas, ou melhor, até que a quantidade de loops que o laço executou tenha atingido o valor de (variável que armazena a quantidade de anulações que devem ser feitas).
Passo 6
Após termos anulado todas as posições informadas pelo arquivo, basta imprimirmos a matriz resultante na tela:
Resposta
Ei, a resposta está no passo a passo :)