Você está na página 1de 36

Técnicas de

Programação:
Manipulação de Arquivos
PROF. PROTÁSIO
DEE-UFPB
Canais (fluxo) e Arquivos
2
 Canal (stream)
 É um mecanismo lógico do sistema de E/S de C que
fornece uma interface entre o programador e os
diversos dispositivos de hardware (teclado, terminal de
vídeo, unidades de disco etc.)
 Arquivo
 É um mecanismo lógico diretamente relacionado com
o dispositivo de hardware real.

Abstração

Programador  CANAL  ARQUIVO  Máquina


Canais (fluxo) e Arquivos
3
 Para o programador todo canal tem o mesmo
comportamento e independente do dispositivo
real.

 O arquivo depende do dispositivo real.

 Assim, o uso de canais facilita o uso dos


arquivos e o programador torna-se
independente de plataforma.
Associação de canais(fluxo) com arquivos
4
 Para realizar E/S em arquivo, utiliza-se
 fstream.h
 Abrindo e fechando um arquivo
 Em C++ um arquivo é aberto pela ligação em um
fluxo.
 Existem três tipos de fluxo:
 entrada,
 saída e
 entrada/saída.
Associação de canais(fluxo) com arquivos
5
 Para abrir um fluxo de entrada
 Usa-se a classe ifstream
 Para abrir um fluxo de saída
 Usa-se a classe ofstream
 Para abrir fluxos de entrada como de saída
 Usa-se a classe fstream
 Exemplo
 ifstream in; // entrada
 ofstream out; // saída
 fstream both; // entrada e saída
Escrevendo em arquivos-texto
6
 Exemplo: programa que escreve um inteiro e um valor em
ponto flutuante para um arquivo chamado teste.txt
#include <iostream>
#include <fstream>

int main (void)


{
// abre um arquivo para escrita de nome Teste.txt
std::ofstream out( "Teste.txt" );
if( !out )
{
std::cout << "O arquivo não pode ser aberto!";
return 1;
}
out << 10 << " " << 123.23 << std::endl;
// fecha o arquivo
out.close();
return 0;
}
Lendo arquivos-texto
7
 Exemplo: programa que lê um inteiro e um valor em ponto
flutuante do arquivo criado pelo programa anterior.
#include <iostream>
#include <fstream>

int main (void)


{
char ch; // guarda o caractere lido
int i; // guarda o inteiro lido
float f; // guarda o número real lido
std::ifstream in( "Teste.txt" ); // abre um arquivo para leitura
if( !in )
{
std::cout << "O arquivo não pode ser aberto!";
return 1;
}
in >> i;
in >> f;
in >> ch;
std::cout << i << " " << f << std::endl;
// fecha o arquivo
in.close();
return 0;
}
Exercício
8
 Faça um programa que salve em arquivo os
seguintes dados e nesta ordem:
 Matrícula do aluno em inteiro
 Primeira nota em float
 Segunda nota em float
 Terceira nota em float
Exercício
9
 Faça um programa que abra o arquivo anterior
e mostre na tela a média final do aluno:
 Matrícula do aluno em inteiro
 Primeira nota em float
 Segunda nota em float
 Terceira nota em float
Fluxo de arquivos e Fluxo de E/S
10
 Os objetos fsteam herdam de iostream
 Assim, todas as funções-membro, operadores e
manipuladores que pertencem à iostream também
podem ser aplicados a fluxos de arquivos.

iostream

fstream

 Exemplo:
 cout << "ufpb" << endl;
 fout << "ufpb" << endl; // sendo que fout é um
// fluxo de arquivo
Arquivos em C++
11
 O C++ visualiza cada arquivos como uma
sequência de bytes

 Cada arquivo terminar com um marcador de fim


de arquivo
 O C++ não impõe nenhuma estrutura a um
arquivo.
 Assim, cada programador deve estruturar arquivos
para atender aos requisitos do aplicativo.
Tipos de acesso em arquivo
12
 Acesso sequencial

0 1 2 3 4 5 6 7 8 n-1

Marcador de fim de arquivo


(EOF)

 Acesso aleatório

0 100 200 300 400 500 Deslocamentos


de bytes

100 bytes 100 bytes 100 bytes 100 bytes 100 bytes 100 bytes
Acesso sequencial
13
 O programa a seguir foi elaborado para que o
arquivo seja estruturado de forma sequencial
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
Função open = abrir arquivo
using namespace std;
Modo de Abertura do Arquivo
int main() { ios::out = arquivo de saída
int numero;
string Nome;
ofstream Saida;
Saida.open("saida.txt", ios::out);
if (!Saida) {
cout << "Arquivo saida.txt nao pode ser aberto" << endl;
abort();
}
cout << "Entre com o numero e nome do aluno\n" << “Digite <Ctrl-Z> para fim de arquivo\n\n-> \n";
while(cin >> numero >> Nome) {
Saida << numero << " " << Nome << "\n"; É true até usuário digitar <Ctrl-Z>
cout << "-> \n";
}
Saida.close();
return 0;
}

Opcional: quando o destrutor do


objeto fstrem já fecha o arquivo.
Modo de abertura do arquivo
14
ofstream Saida;
Saida.open("saida.txt", ios::out);

 É equivalente à
ofstream Saida ("saida.txt", ios::out);
 Ou

ofstream Saida ("saida.txt");

 Outros modos de abertura


Exemplo
15
 O que o programa abaixo realiza?

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
int numero;
string Nome;
ofstream Saida;
Saida.open("saida.txt", ios::out);
if (!Saida) {
cout << "Arquivo saida.txt nao pode ser aberto" << endl;
abort();
}
cout << "Entre com o numero e primeiro nome do aluno\n" << "Digite <Ctrl-Z> para fim de arquivo\n\n-> \n";
cin >> numero >> Nome;
while(! cin.eof()){ // final de dados?
Saida << numero << " " << Nome << '\n';
cout << "-> \n";
cin >> numero >> Nome;
}
Saida.close();
return 0;
}
Exercício
16
 Faça um programa que recupere os dados do
arquivos do programa anterior.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <string>
using namespace std;
int main() {
int numero;
string nome;
ifstream Entrada;
Entrada.open("saida.txt", ios::in);
if (! Entrada)
{ cout << "Arquivo saida.txt nao pode ser aberto" << endl;
abort();
}
cout << "Numero" << " " << "Nome" << endl;

while(Entrada >> numero >> nome)


cout << numero << " " << nome << endl;
Entrada.close();
return 0;
}
Buffer de arquivo
17
 Ao realizar uma escrita em arquivo
 Os dados não são enviados diretamente para o arquivo
 São armazenados temporariamente em uma área de
memória (buffer).

abc123...

 Quando o buffer estiver cheio, é descarregado no disco pelo


S.O.
 Quando o arquivo é fechado, também é descarregado
 Em C++ para forçar a descarga do buffer:
 Inserir endl
 Insere um caracter de fim-de-linha (´\n´) e descarregar (flush) o buffer
 Ou através da executação de:
 Saida<< flush;
Problema com acesso sequencial
18
 Considere que foi digitado os dados do programa
de escrita anterior:
1 Joao
2 Maria
3 Jose
 No arquivo, os dados estariam dispostos como
1 Joao<CR><LF>2 Maria<CR><LF>3 JoseEOF
 Suponha que se queira trocar Maria por Marialice
1 Joao<CR><LF>2 MarialiceJoseEOF
 A estrutura do arquivo estaria corrompida
Solução
19
 Criar para cada registro no arquivo espaços
suficientes (máximo) para modificações
1 Joao<CR><LF>2 Maria<CR><LF>3 JoseEOF

10 30 10 30 10 30
caracteres caracteres caracteres caracteres caracteres caracteres

1 Joao <CR><LF>2 Maria <CR><LF>3 Jose EOF


Preparando um arquivo com acesso aleatório
20
#include <iostream>
#include <fstream>
#include <iomanip> // Para manipuladores de stream: setw, left, etc.
#include <string>
using namespace std;

int main() {
int numero;
string nome;
ofstream Entrada;
Entrada.open("saida.txt", ios::out);
if (! Entrada) {
cout << "Arquivo saida.txt nao pode ser aberto" << endl;
abort();
}
cout << "Numero" << " " << "Nome" << endl;

while (cin >> numero){


cin.ignore(1);
getline (cin, nome, '\n');
nome.resize(30);
Entrada << left << setw(10) << numero << " " << setw(30) << nome << endl;
}

return 0;
}
Preparando um arquivo com acesso aleatório
21

1 Maria Aparecida...............
1..........Maria Aparecida
2 Joao Miguel da Silva e Souza
2..........Joao Souza..
3 Sirineu Sirino
3..........Sirineu Sirino................
Acesso Aleatório
22
 Em C++, o acesso aleatório é realziado usando
as funções
 seekg( )
 Seta a posição do próximo caractere a ser lido pela
stream de entrada.
 seekp( )
 Seta a posição onde o próximo caractere será inserido
na stream de saída.
Acesso Aleatório
23
 seekg( )
 seekg (posição);
 posição : novo valor absolute relativo à origem
 Exemplo
 ifstream Entrada("saida.txt", ios::in);
 Entrada.seekg(10); // lerá o 10º caractere do arquivo

 seekg (offset, origem);


 offset: deslocamento relative ao parâmetro origem
 origem:
valor offset relativo à
beg Início da stream
cur Posição corrente da stream
end Fim da stream

 Exemplo
 Entrada.seekg(10, Entrada.beg);
 Entrada.seekg(0, Entrada.end);
Acesso Aleatório
24
 tellg
 Retorna a posição do caractere corrente na stream de
entrada
 int length = Entrada.tellg();

 tellp
 Retorna a posição do caractere corrente na stream de
saída
 long pos = Saida.tellp();
Exemplo com tellp e seekp
25

#include <fstream>

int main () {

std::ofstream outfile;
outfile.open ("test.txt");

outfile.write ("This is an apple",16);


long pos = outfile.tellp();
outfile.seekp (pos-7);
outfile.write (" sam",4);

outfile.close();

return 0; write (const char* s, streamsize n);


} Insere os primeiros n caracteres
da array apontada por s
Exemplo com tellg e seekg
// Lê um arquivo e coloca na memória
#include <iostream> // std::cout
26
#include <fstream> // std::ifstream

using namespace std;

int main () {
ifstream Entrada ("test.txt");

if (Entrada) {
// Computar o comprimento do arquivo
Entrada.seekg (0, Entrada.end);

int length = Entrada.tellg();

Entrada.seekg (0, Entrada.beg); read(char* s, streamsize n);


// Alocar memoria:
Extrai n caracteres da stream e
char * buffer = new char [length]; armazena na array apontada por s
// Ler dados do arquivo e salvar no buffer
Entrada.read (buffer,length);

Entrada.close();

// Imprimir o tamanho do arquivo


cout << endl << "Tamanho do arquivo: " << length << "bytes" << endl;

// Imprimir o conteúdo do arquivo


cout.write (buffer, length);

delete[] buffer;
}
return 0;
}
Retornando ao arquivo formatado para acesso
aleatório 27

1 Maria Aparecida...............
1..........Maria Aparecida
2 Joao Miguel da Silva e Souza
2..........Joao Souza..
3 Sirineu Sirino
3..........Sirineu Sirino................
Recuperando dados com acesso Aleatório
28
#include <iostream>
#include <fstream>
#include <iomanip> // Para manipuladores de stream: setw, left, etc.
#include <string>
using namespace std;

int main() {
int numero, temp;
string nome;
ifstream Entrada("saida.txt", ios::in);
if (! Entrada) {
cout << "Arquivo saida.txt nao pode ser aberto" << endl;
abort();
}

cout << "Digite o numero do registro: " << endl;

cin >> numero;

Entrada.seekg( (numero-1) * (10 + 1 + 30 + 2)); // 10 de numero, 1 do espaço, 30 de nome e 2 <CR><LF>

Entrada >> temp;

getline (Entrada, nome, '\n');

cout << nome;

return 0;
}
Modificando dados com acesso aleatório
#include <iostream> 29
#include <fstream>
#include <iomanip> // Para manipuladores de stream: setw, left, etc.
#include <string>
using namespace std;

int main() {
int numero, posicao;
string nome;
fstream Entrada("saida.txt", ios::in|ios::out);
if (! Entrada) { cout << "Arquivo saida.txt nao pode ser aberto" << endl; abort(); }

cout << "Digite o numero do registro: " << endl;


cin >> numero;
posicao = (numero-1) * (10 + 1 + 30 + 2 + 10 + 1);
// 10 de numero, 1 do espaço, 30 de nome, 2 <CR><LF>, 10 de numero e 1 do espaço
Entrada.seekg(posicao);
getline (Entrada, nome, '\n');
cout << nome;
cout << endl << "Digite o novo nome:" << endl;
cin.ignore(); // Ignora o <Enter>
nome.clear();
nome.resize(30);
getline (cin, nome, '\n');
Entrada.seekp(posicao);
Entrada << left << setw(30) << nome << endl;
return 0;
}
Funções get( ) e put( )
30
 get()
 istream &get( char ch );
 Lê um único caractere do fluxo associado, coloca o
valor em ch retorna o fluxo.
 put()
 ostream &put( char ch )
 Escreve ch para o fluxo e retorna o fluxo.
Exemplo com put()
31

#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
char *p = "Alô a todos!";
// abre um arquivo para escrita
ofstream out( "Test.txt" );
if( !out )
{
cout << "O arquivo não pode ser aberto!";
return 1;
}
while( *p )
out.put( *p++ );

return 0;
}
Exemplo com get()
32
#include <iostream>
#include <fstream>

using namespace std;

int main ( )
{
// declaração das variáveis
char ch; // guarda o caractere lido

ifstream in( "test.txt");


if( !in )
{
cout << "O arquivo não pode ser aberto!";
return 1;
}
while( in )
{
// in será zero quando eof (fim do arquivo) for encontrado
in.get( ch );
cout << ch;
}

return 0;
}
Salvando objetos em arquivo
33
 Exemplo: criando o arquivo inicial para salvar
dados de contas bancárias
#include <iostream>
#include <fstream>

using namespace std;

struct conta {
int numero;
char nome[30];
float saldo;
};

int main() {
conta contavazia = {0, "", 0.0};
ofstream Sfile("contas.txt",ios::out);
if(! Sfile) { cerr << "Fala em abrir o arquivo!!!" << endl; return 1;
}

for (int i = 0; i < 100; i++)


Sfile.write((const char *)(&contavazia),sizeof(conta));

return 0;
}
Salvando objetos em arquivo: inserir dados
34
#include <iostream>
#include <fstream>

using namespace std;

struct conta
{
int numero;
char nome[30];
float saldo;
};

int main() {
conta c;
ofstream Sfile("contas.txt",ios::ate);
if(! Sfile) { cerr << "Arquivo credito.dat nao pode ser aberto." << endl; return 1; }

cout << "Enter numero da conta de 1 a 100 (0 termina) ";


cin >> c.numero;
while(c.numero > 0 && c.numero <= 100) {
cout << "Entre nome, saldo\n? ";
cin >> c.nome >> c.saldo;
// posicionar no cliente desejado
Sfile.seekp((c.numero - 1) * sizeof(conta));
// atualizar dados
Sfile.write((const char *)(&c),sizeof(conta));
cout << "Enter numero da conta de 1 a 100 (0 termina) ";
cin >> c.numero;
}
return 0;
}
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std; Salvando objetos
struct conta em arquivo: 35
recuperar dados
{
int numero;
char nome[30];
float saldo;
};

int main() {
conta c;
ifstream Sfile("contas.txt", ios::in);

if(! Sfile) { cerr << "Falha em abrir o arquivo!!!" << endl; return 1; }

cout << setiosflags(ios::left) // Comando para setar flags - ios::left = alinhar à esquerda
<< setw(10) << "Conta" // setw(n) lê ou escreve o valor em w caracteres
<< setw(30) << "Nome"
<< resetiosflags(ios::left)// reseta flags ios::left
<< setw(10) << "Saldo" << endl;

Sfile.read((char *)(&c),sizeof(conta));

while (Sfile && ! Sfile.eof()){


if(c.numero != 0)
cout << setiosflags(ios::left)
<< setw(10) << c.numero
<< setw(30) << c.nome
<< setw(10) << setprecision( 2 ) << resetiosflags(ios::left)
// setprecision(n) precisão em ponto flutuante setada em "n"
<< setiosflags(ios::fixed | ios::showpoint) << c.saldo << '\n';
// flag "fixed" imprime pontos flutuantes em notação decimal
// flag "showpoint" sempre gera um ponto decimal
Sfile.read((char *)(&c),sizeof(conta));
}
return 0;
}
Exercício
36
 Faça um programa de cadastro da turma
(nome, CRE, matrícula e período) considerando
que cada aluno é modelado em um objeto e
salve em arquivos os dados.
 Observações:
 Quando o programa for finalizado, o arquivo deve
manter os dados
 Quando o programa for executado, o usuário possa
inserir novos dados no arquivo

Você também pode gostar