Buscar

14. Manipulação de Arquivos

Prévia do material em texto

Ju
d
so
n
 S
an
to
s 
S
an
ti
ag
o
MANIPULAÇÃO DE ARQUIVOS
Programação de Computadores
 Frequentemente no computador a entrada 
de dados é feita pelo teclado e a saída de 
dados é feita em tela
Introdução
Programa
Exibicao do time
-----------------------------------------
Nome Gols Partidas
-----------------------------------------
Bebeto (ex-Vasco) 760 900
Neto (ex-Corinthians) 102 400
Pele (ex-Santos) 1000 800
-----------------------------------------
Press any key to continue . . .
Exibicao do time
-----------------------------------------
Nome Gols Partidas
-----------------------------------------
Bebeto (ex-Vasco) 760 900
Neto (ex-Corinthians) 102 400
Pele (ex-Santos) 1000 800
-----------------------------------------
Press any key to continue . . .
Introdução
 As vezes a entrada de dados pelo teclado não 
é a melhor opção:
 Imagine usar o teclado para entrar com nome, 
preço e quantidade em estoque de 1000 produtos
Programa
Entrada
Introdução
 As vezes a saída de dados na tela não é a 
melhor opção:
 Seria conveniente gerar uma lista de compras de 
produtos fora de estoque em um arquivo
Programa
Saída
Introdução
 Hoje em dia quase a totalidade dos programas 
de computador trabalham com arquivos:
 Editores de texto, planilhas e apresentações criam 
documentos em arquivos
 Editores de imagens, vídeos e sons criam, organizam e 
guardam informações em arquivos
 Compiladores lêem o arquivo fonte de um programa e 
geram um arquivo executável
 Um arquivo é um conjunto de bytes armazenado 
em algum dispositivo
Introdução
 O sistema operacional se encarrega de:
 Gerenciar os arquivos
 Saber a localização dos arquivos
 Guardar informações como tamanho, data de 
criação, última modificação, etc.
 Como programador estamos interessados em 
conectar um programa a um arquivo para:
 Ler informações do arquivo
 Gravar informações no arquivo
Introdução
 Para um programador os arquivos se dividem 
em duas categorias:
 Arquivos texto: uma sequência de bits em que um 
conjunto de n bits representam um caractere:
 Na codificação ASCII um caracatere são 8 bits
 Em Unicode um caractere tem de 8 a 32 bits
 Existem várias codificações (UTF-8, UTF-16, UTF-32)
01000001 01110010 01110001 01110101 01101001 01110110 01101111 01110011 00100000 00001010
'A' 'r' 'q' 'u' 'i' 'v' 'o' 's' ' ' '\n'
Arquivo texto na codificação ASCII
00000000000000000000000000001111
Introdução
 Para um programador os arquivos se dividem 
em duas categorias:
 Arquivos binários: uma sequência de bits em 
que um conjunto de n bits representam uma 
informação na sua representação nativa 
(inteira, ponto-flutuante, caractere, etc.)
00111110110000000000000000000000 01101001 01110110 01101111 01110011 00100000
0.375 'c' 'a' 's' 'a' '\0' 15
Arquivo binário
float intchar []
Introdução
 Diferença entre arquivos texto e binário:
01101001
'0' '.' '3' '7' '5'
Representação binária de 0.375
0 0111110 110000000000000000000000
mantissaexpoentesinal
01101001 01101001 01101001 01101001
Representação texto de 0.375
Introdução
 A entrada e saída de arquivos em C++ é muito 
parecida com a entrada e saída no console
Programa
Console
Arquivo
Console
ArquivoSaídaEntrada
Entrada e Saída
 Quando utiliza-se cin para ler dados, o 
programa vê a entrada como uma série de 
bytes (caracteres):
 Suponha que você digite a seguinte entrada:
 A entrada é um conjunto de caracteres (bytes) 
armazenados no buffer de entrada
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
38.5 19.2
Entrada e Saída
 Cada byte é interpretado como um código de 
um caractere (tabela ASCII)
 Não importa o tipo de destino, a entrada é feita 
com o tipo caractere, ou seja, texto
 cin tem a responsabilidade de traduzir o texto 
para o tipo da variável utilizada
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
cin >> total;
Entrada e Saída
 Entrada usando uma variável tipo char:
 O primeiro caractere da entrada é atribuído 
para a variável, nenhuma tradução acontece
38.5 19.2
char ch;
cin >> ch;
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
00110011 ch
Entrada e Saída
 Entrada usando uma variável tipo int:
 A leitura é feita até encontrar o primeiro 
caractere que não é um dígito
38.5 19.2
int n;
cin >> n;
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
n= 00000000 00000000 00000000 00100110'3' '8'
38
Entrada e Saída
 Entrada usando uma variável tipo float:
 A leitura é feita até encontrar um caractere 
que não faz parte de um ponto-flutuante
38.5 19.2
float x;
cin >> x;
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
x= 00000001 00000000 00000001 10000001'3' '8' '.' '5' 
38.5
Entrada e Saída
 Entrada usando um vetor de caracteres:
 A leitura é feita até encontrar um caractere 
em branco, tabulação ou nova linha
38.5 19.2
char nome[50];
cin >> nome;
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
nome='3' '8' '.' '5' 
"38.5"
00110011 00111000 00101110 00110101 00000000
Entrada e Saída
 Entrada usando um vetor de caracteres:
 Usando a função getline, a entrada é lida até 
o caractere de nova linha
38.5 19.2
char nome[50];
cin.getline(nome, 50);
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00001101
'3' '8' '.' '5' ' ' '1' '9' '.' '2' '\n'
nome
"38.5 19.2"
00110011 00111000 00101110 00110101 00100000 00110001 00111001 00101110 00110010 00000000
Entrada e Saída
 Em resumo, o texto digitado pelo teclado é 
recebido sempre em forma de texto e depois 
convertido para o tipo apropriado
 Um arquivo texto se assemelha muito ao buffer do 
teclado, isto é, ele é composto por uma seqüência 
de caracteres
 Um arquivo binário armazena mais que texto:
 Planilhas armazenam dados em formato numérico
 Editores de texto armazenam formatação, fontes, 
imagens, impressoras, etc.
Saída em Arquivos Texto
 Para usar cout num programa é necessário:
 Incluir o arquivo de cabeçalho iostream
 Define uma classe ostream para manipular a saída
 Declara um objeto da classe ostream chamado cout
 Considerar que os objetos estão definidos no 
espaço de nomes std
#include <iostream>
using namespace std;
// ou
using std::cout;
Saída em Arquivos Texto
 Para usar cout num programa é necessário:
 Usar cout com o operador de inserção << para 
mostrar vários tipos de dados diferentes
 Usar cout.setf() e cout.precision() para modificar a 
forma de impressão dos dados
char ch = 'M';
float num = 35.4f;
cout << ch;
cout << num;
float tax = 31.28062;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout.precision(2);
cout << tax;
Saída em Arquivos Texto
 Fazer a saída em arquivos é semelhante:
 Incluiro arquivo de inclusão fstream
 Define uma classe ofstream para manipular a saída
 Criar um objeto do tipo ofstream
 Associar um objeto ofstream com um arquivo do 
disco usando a função open()
 Usar o operador de inserção << com o objeto 
ofstream
 Fechar o arquivo com a função close()
Saída em Arquivos Texto
 O arquivo de inclusão fstream não fornece 
um objeto predefinido, é preciso criar um:
 E associá-lo com um arquivo do disco:
 Para usá-los desta forma:
ofstream fout; // um objeto ofstream
fout.open("pesca.txt"); // fout usado para escrever em pesca.txt
char arquivo[50]; // um vetor de caracteres
cin >> arquivo; // nome definido pelo usuário
fout.open(arquivo); // abre arquivo definido pelo usuário
double wt = 125.8; 
fout << wt; // escreve um número em pesca.txt
char linha[81] = "Objetos são variáveis de uma classe";
fout << linha << endl; // escreva uma linha de texto
Saída em Arquivos Texto
// escrevendo em arquivo texto
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char carro[50];
int ano;
float precoN; // preço normal
flaot precoP; // preço promocional
ofstream fout; // cria objeto para saída
fout.open("carinfo.txt"); // associa com arquivo
cout << "Entre com a marca e modelo do carro: ";
cin.getline(carro, 50);
cout << "Entre com o ano: ";
cin >> ano;
cout << "Digite o preço normal: ";
cin >> precoN;
precoP = 0.913 * precoN;
Saída em Arquivos Texto
// mostrando informações na tela
cout << fixed;
cout.precision(2);
cout << "Marca e modelo: " << carro << endl;
cout << "Ano: " << ano << endl;
cout << "Preço normal: R$" << precoN << endl;
cout << "Preço promocional: R$" << precoP << endl;
// gravando informações no arquivo
fout << fixed;
fout.precision(2);
fout << "Marca e modelo: " << carro << endl;
fout << "Ano: " << ano << endl;
fout << "Preço normal: R$" << precoN << endl;
fout << "Preço promocional: R$" << precoP << endl;
fout.close();
system("pause");
return 0;
}
Saída em Arquivos Texto
 Saída do programa:
 Arquivo carinfo.txt:
Entre com a marca e modelo do carro: Ford Ka
Entre com o ano: 2009
Digite o preço normal: 28576
Marca e modelo: Ford Ka
Ano: 2009
Preço normal: R$28576.00
Preço promocional: R$26089.89
Marca e modelo: Ford Ka
Ano: 2009
Preço normal: R$28576.00
Preço promocional: R$26089.89
Saída em Arquivos Texto
 O método open():
 Cria um novo arquivo se ele não existir
 Sobrescreve o arquivo, se ele existir
 A abertura de um arquivo pode falhar caso o 
arquivo utilizado seja um arquivo de acesso 
restrito:
 Por exemplo, um arquivo já aberto em outro 
programa ou um arquivo protegido do S.O.
fout.open("carinfo.txt"); // associa com arquivo
Leitura de Arquivos Texto
 Para usar cin num programa é necessário:
 Incluir o arquivo de inclusão iostream
 Define uma classe istream para manipular a entrada
 Declara um objeto da classe istream chamado cin
 Considerar que estes objetos estão definidos no 
espaço de nomes std
#include <iostream>
using namespace std;
//ou
using std::cin;
Leitura de Arquivos Texto
 Para usar cin num programa é necessário:
 Usar cin com o operador de extração >> para ler 
vários tipos de dados diferentes
 Usar cin.get() para ler caracteres individuais ou 
cin.getline() para ler uma linha por vez
char ch;
float num;
cin >> ch;
cin >> num;
char ch;
char nome[30];
cin.get(ch);
cin.getline(nome, 30);
Leitura de Arquivos Texto
 A leitura de arquivos é muito semelhante:
 Incluir o arquivo de cabeçalho fstream
 Define uma classe ifstream para manipular a 
entrada
 Criar um objeto do tipo ifstream
 Associar um objeto ifstream com um arquivo do 
disco usando a função open()
 Usar o operador de extração >>, o método get() 
ou getline() com o objeto ifstream
 Fechar o arquivo com a função close()
Leitura de Arquivos Texto
 O arquivo de inclusão fstream não fornece 
um objeto predefinido, é preciso criar um:
 E associá-lo com um arquivo do disco:
 Para usá-los desta forma:
ifstream fin; // outro objeto ifstream
fin.open("boliche.txt"); // fin usado para ler boliche.txt
char arquivo[50]; // um vetor de caracteres
cin >> arquivo; // nome definido pelo usuário
fin.open(arquivo); // abre arquivo definido pelo usuário
double wt; 
fin >> wt; // lê um número de boliche.txt
char linha[81];
fin.getline(linha, 81); // lê uma linha de texto
Leitura de Arquivos Texto
 Se o arquivo não existir no disco, todas as 
tentativas de uso do objeto ifstream vão 
falhar
 A melhor forma de checar se um arquivo foi 
aberto corretamente é através do método 
is_open()
fin.open("boliche.txt");
if (!fin.is_open())
{
cout << "A abertura do arquivo falhou!" << endl;
system("pause");
exit(EXIT_FAILURE);
}
Leitura de Arquivos Texto
// lendo arquivos texto
#include <iostream>
#include <fstream>
using namespace std;
const int TAM = 60;
int main()
{
char arquivo[TAM];
ifstream fin; // cria objeto para leitura de arquivo
cout << "Digite nome do arquivo: ";
cin.getline(arquivo, TAM);
fin.open(arquivo); // associa com arquivo do disco
if (!fin.is_open()) // a abertura do arquivo falhou
{
cout << "A abertura do arquivo " << arquivo << " falhou!" << endl;
cout << "Programa encerrando.\n";
system("pause");
exit(EXIT_FAILURE);
}
Leitura de Arquivos Texto
double valor;
double soma = 0.0; // soma dos itens
int cont = 0; // número de itens lidos
fin >> valor; // lê primeiro valor
while (fin.good()) // enquanto a entrada for boa e não eof
{
++cont; // mais um item lido
soma += valor; // acumula valores lidos
fin >> valor; // lê próximo valor
}
if (fin.eof())
cout << "Fim de arquivo alcançado.\n";
else
if (fin.fail())
cout << "Tipo incorreto de dado na entrada.\n";
else
cout << "Entrada encerrada por razão desconhecida.\n";
Leitura de Arquivos Texto
if (cont == 0)
cout << "Nenhum valor processado.\n";
else
{
cout << "Itens lidos: " << cont << endl;
cout << "Soma: " << soma << endl;
cout << "Média: " << soma / cont << endl;
}
fin.close(); // fecha o arquivo
system("pause");
return 0;
}
Leitura de Arquivos Texto
 Arquivo "pontos.txt":
 Saída do programa:
18 19 18.5 13.5 14
16 19.5 20 18 12 18.5
17.5
Digite nome do arquivo: pontos.txt
Fim de arquivo alcançado.
Itens lidos: 12
Soma: 204.5
Média: 17.0417
Modos de Abertura
 Ao abrir um arquivo pode-se passar um 
segundo argumento com o modo de abertura
 O modo de abertura do arquivo permite 
configurar como o arquivo será aberto:
 Escrita de dados
 Leitura de dados
 Adição de dados
 Modo texto ou binário 
fin.open("boliche.txt", ios_base::in);
Modos de Abertura
 A tabela abaixo lista as constantes que 
podem ser usadas para o modo de abertura:
Constante Significado
ios_base::in Abre arquivo para leitura
ios_base::out Abre arquivo para escrita
ios_base::app Acrescenta ao final do arquivo
ios_base::trunc Limpa arquivo, se ele existir
ios_base::binary Cria arquivo binário
ios_base::nocreate Falha se arquivo não existir
ios_base::noreplace Falha se arquivo já existir
Modos de Abertura
 Omitindo o modo de abertura do arquivo faz 
com que sejam usados os valores padrão:
 Ifstream
 Ofstream
 Para escrever dados sem apagar o arquivo:
fin.open("boliche.txt", ios_base::in);
fout.open("pesca.txt", ios_base::out |ios_base::trunc);
ofstream fout;
fout.open("append.txt", ios_base::out | ios_base::app);
Arquivos Binário
 São arquivos que guardam a informação em 
sua representação binária (ex.: Word 2003)
01101001
'0' '.' '3' '7' '5'
Representação binária de 0.375
0 0111110 110000000000000000000000
mantissaexpoentesinal
01101001 01101001 01101001 01101001
Representação texto de 0.375
Arquivos Binários
 A entrada e saída de arquivos binários é 
usualmente feita com registros
 Para salvar o registro num arquivo binário:
struct planeta
{
char nome[20]; // nome do planeta
double populacao; // número de habitantes
double gravidade; // aceleração da gravidade
};
planeta p = {"Terra", 6820400000, 9.81};
ofstream fout;
fout.open("planetas.dat", ios_base::out | ios_base::binary);
fout.write( (char*) &p, sizeof p);
Arquivos Binários
 O método write() copia uma quantidade de 
bytes da memória para um arquivo
 A instrução vai para o endereço de p e copia 36
bytes (o tamanho do registro planeta) para o 
arquivo associado a fout (planetas.dat)
 A conversão do endereço do registro para um 
ponteiro para char é necessária para usar write()
ofstream fout;
fout.open("planetas.dat", ios_base::out | ios_base::binary);
fout.write( (char*) &p, sizeof p);
Arquivos Binários
 Para recuperar a informação gravada no 
arquivo é preciso usar o mesmo registro
 Para ler o registro de um arquivo binário:
struct planeta
{
char nome[20]; // nome do planeta
double populacao; // número de habitantes
double gravidade; // aceleração da gravidade
};
planeta nv;
ifstream fin;
fin.open("planetas.dat", ios_base::in | ios_base::binary);
fin.read( (char*) &nv, sizeof nv);
Arquivos Binários
// entrada e saída em arquivos binários
#include <iostream>
#include <fstream>
using namespace std;
struct planeta 
{
char nome[20]; // nome do planeta
double populacao; // número de habitantes
double gravidade; // aceleração da gravidade
};
int main()
{
planeta p;
ifstream fin; // cria objeto para leitura de arquivo
fin.open("planetas.dat", ios_base::in | ios_base::binary);
// continua
Arquivos Binários
if (fin.is_open()) // se o arquivo foi aberto sem erros
{
cout << "Aqui esta o conteúdo do arquivo:" << endl; 
while (fin.read((char *) &p, sizeof p))
{
cout << p.nome << " "
<< p.populacao << " "
<< p.gravidade << endl;
}
fin.close();
} 
// acrescenta mais dados
ofstream fout;
fout.open("planetas.dat", ios_base::out | ios_base::app | ios_base::binary);
if (!fout.is_open())
{
cout << "Arquivo não pode ser aberto!" << endl;
system("pause");
exit(EXIT_FAILURE);
} 
// continua
Arquivos Binários
cout << "\nNome do planeta: ";
cin >> p.nome;
cout << "Populacao: ";
cin >> p.populacao;
cout << "Gravidade: ";
cin >> p.gravidade;
fout.write((char *) &p, sizeof p);
fout.close();
fin.open("planetas.dat", ios_base::in | ios_base::binary);
if (fin.is_open())
{
cout << "\nAqui esta o conteúdo do arquivo:" << endl; 
while (fin.read((char *) &p, sizeof p)) {
cout << p.nome << " " << p.populacao << " "
<< p.gravidade << endl;
}
fin.close();
} 
system("pause");
return 0;
}
Arquivos Binários
 Saída do programa:
Aqui esta o conteudo do arquivo:
Terra 6820400000 9.81
Marte 2 9.81
Venus 0 6.53
Mercurio 0 8.88
Nome do planeta: Plutao
Populacao: 0
Gravidade: 3.10
Aqui esta o conteudo do arquivo:
Terra 6820400000 9.81
Marte 2 9.81
Venus 0 6.53
Mercurio 0 8.88
Plutao 0 9.20
Conclusão
 Entrada e saída de dados em arquivos é um 
recurso muito utilizado em programas
 Os dados podem ser armazenados em:
 Arquivos texto: podem ser lidos por qualquer 
editor de texto e são altamente portáveis
 Arquivos binários: são mais precisos para 
armazenar números ponto-flutuante, as 
operações de leitura e escrita são mais rápidas, 
mas geralmente ocupam mais espaço

Continue navegando