Operadores

Transcrição

Operadores
Entrada e Saída
Julia – Tecgraf PUC-Rio
Agosto 2010
Exemplo de entrada em arquivo
#include <fstream>
#include <iostream>
using namespace std;
classe que representa um stream
para um arquivo de saída
int main()
{
ifstream file("exemplo1.txt");
char ch;
while(!file.eof())
a função eof() ...
{
file.get(ch);
cout << ch;
a função get() ...
}
file.close();
}
o arquivo deve ser fechado após seu uso
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
2
Streams de Entrada e Saída
• Abstração que representa uma sequência de
bytes
– Input: de um dispositivo (disco, teclado, etc)
para a memória
– Saída: da memória para um dispositivo
(impressora, console, etc)
• Orientação a objetos
– Tipo Abstrato de Dados (Standard I/O, files,
blocos de memória, etc)
– Redefinição de operadores
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
3
Streams de Entrada e Saída
• Low-level I/O
– Não formatado
– Transferência byte-a-byte
– Eficiência para transmissão de grande volume de
dados
• High-level I/O
– Formatado
– Bytes agrupados (inteiros, caracteres, strings,
etc)
– Adequado para a maior parte das necessidades
de I/O
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
4
Streams de Entrada e Saída
• Em C++, existem diferentes tipos de streams
de entrada (istream) e saída (ostream)
• Por exemplo:
– ifstream e ofstream para arquivos
– istrstream e ostrstream para char*
– istringstream e ostringstream para objetos
String de C++
• Todos os tipos de streams de entrada e saída
mantém uma interface comum
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
5
Standard Library: iostream
• Possui as funcionalidades para manipulação
de entrada/saída em C++
– Basic class templates: classes básicas virtuais
– Class template instantiations: implementação de
classes básicas para manipular elementos do tipo
char (narrow-oriented) e wchar_t (wide
oriented)
– Standard objects: o header <iostream> define
objetos de e/s padrão stdin, stdout e stderr
– Manipulators: funções globais (ex: endl, hex,
scientific) para uso com os operadores << e >>
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
6
Visão geral das bibliotecas
•
<ios>, <istream>, <ostream>, <streambuf> e <iosfwd> contém classes
bases da hierarquia e não costumam ser incluídos diretamente na maioria
dos programas c++
•
<iostream> declara objetos usados para entrada e saída padrão
•
<fstream> declara classes para entrada e saída em arquivos
•
<sstream> declara classes para manipular strings como streams
•
<iomanip> declara standard manipulators para uso com << e >>
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
7
Operadores << e >>
• Os operadores << e >> são usados para
simplificar as operações de entrada e saída
formatadas, em todos os tipos de streams
<<
– Inserter Operator
– Usado para inserir dados em um dispositivo de
saída
>>
– Extractor Operator
– Usado para extrair dados de um dispositivo de
entrada
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
8
Exemplo de uso do operador <<
#include <fstream>
using namespace std;
Nesse arquivo estão definidas
várias classes usadas para file i/o
classe que representa um stream
int main()
para um arquivo de saída
{
ofstream file("exemplo1.txt");
file << "Esse e' um primeiro exemplo de
saida em arquivo";
file.close();
operador << que tem como argumento
o conteúdo a ser escrito
return 0;
}
o arquivo deve ser fechado após seu uso
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
9
Output Stream
• A classe ostream representa uma sequência de
bytes de saída
• Suporta saída formatada e não formatada
• Instâncias da classe ostream definidas em
<iostream>
– cout: representa a saída padrão (stdout)
– cerr: representa a saída padrão para erros (stderr)
– clog: representa a saída padrão para log
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
10
Formatação da saída em ostream
• O operador << é usado para formatar os
dados enviados a um ostream
– Ex: um valor numérico é escrito como uma
sequência de caracteres
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
ostream&
08/09/10
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
operator<<
(bool& val );
(short& val );
(unsigned short& val );
(int& val );
(unsigned int& val );
(long& val );
(unsigned long& val );
(float& val );
(double& val );
(long double& val );
(const void* val );
POO Avançado - Copyright Tecgraf PUC-Rio
11
Manipulators
• São funções especiais usadas em conjunto
com os operadores << e >>
• Definidos em <iomanip>
• Alguns são específicos para entrada ou saída
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
12
Exemplos de manipuladores de saída
endl
Insere newline
ends
Insere o caractere null ( '\0')
flush
Fz flush no buffer usado pelo stream
dec
Altera a base numérica para decimal
hex
Altera a base numérica para hexadecimal
oct
Altera a base numérica para octal
scientific
Usa notação científica
fixed
Usa notação em ponto fixo
setprecision
Altera a precisão das casas decimais (possui parâmetro)
setfill
Altera o carectere de preenchimento (possui parâmetro)
setw
Altera o número de caracteres usado como largura (possui
parâmetro)
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
13
Exemplos de manipulators de saída
cout
cout
cout
cout
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
08/09/10
1331 << endl;
hex<< 1331 << endl;
1331.123456 << endl;
scientific << 1331.123456 << endl;
fixed << 1331.123456 << endl;
setprecision(3) << 1331.123456 << endl;
dec << 1331 << endl;
setfill('X') << setw(8) << left << 1331 << endl;
true << false << endl;
boolalpha << true << false << endl;
POO Avançado - Copyright Tecgraf PUC-Rio
14
Saída não formatada
• Funções put e write
– ostream& put (char c);
Escreve o caractere c no buffer de saída
– ostream& write (const char* s , streamsize n);
Escreve no buffer de saída o bloco de caracteres
apontado por s e de tamanho n
– Podem ser chamados em cascata
– Permitem parâmetros numéricos (ASCII)
cout.put('A').put('B').put('C').put('\n');
cout.put(65).put(66).put(67).put('\n');
const char* v = "ABCD";
cout.write (v, 4).put('\n');
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
15
Ouput em tipos definidos pelo usuário
• A classe pode definir o operador << seguindo
o mesmo padrão dos tipos primitivos
class person {
public:
int age;
string name;
person (int _age, string _name) {
age = _age;
name = _name;
}
};
ostream& operator<<(ostream &os, const person &p) {
return os << p.name << " tem " << p.age << " anos";
}
int main() {
person ana(10,"ana maria");
cout << ana << endl;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
16
Especialização de classe com o
operador <<
class person {
public:
int age;
string name;
person (int _age, string _name) {
age = _age;
name = _name;
}
};
ostream& operator<<(ostream &os, const person &p) {
return os << p.name << " tem " << p.age << " anos";
}
class child : public person {
public:
person& parent;
child (int _age, string _name, person& _parent) :
person (_age, _name), parent (_parent) {
}
};
ostream& operator<<(ostream &os, const child &p) {
return os << p.name << " tem " << p.age << " anos e seu responsavel"
<< "é' " << p.parent.name;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
17
Especialização de classe com o
operador <<
int main() {
person p(35,"ana");
cout << p << endl;
child c(10,"pedro", p);
cout << c << endl;
person* p2 = &c;
cout << *p2 << endl;
return 0;
}
> ana tem 35 anos
> pedro tem 10 anos e seu responsavel e' ana
> pedro tem 10 anos
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
18
Especialização de classe com o
operador <<
class person {
public:
int age;
string name;
person (int _age, string _name) {
age = _age;
name = _name;
}
virtual ostream& put (ostream& s) const;
};
ostream& person::put (ostream& s) const {
return s << name << " tem " << age << " anos";
}
ostream& operator<<(ostream &os, const person &p) {
return p.put(os);
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
19
Especialização de classe com o
operador <<
class child : public person {
public:
person& parent;
child (int _age, string _name, person& _parent) :
person (_age, _name), parent (_parent) {
}
ostream& put (ostream& s) const;
};
ostream& child::put (ostream& s) const {
return s << name << " tem " << age << " anos e seu responsavel e' "
<< parent.name;
}
int main() {
person p(35,"ana");
cout << p << endl;
child c(10,"pedro", p);
cout << c << endl;
person* p2 = &c;
cout << *p2 << endl;
return 0;
}
08/09/10
> ana tem 35 anos
> pedro tem 10 anos e seu responsavel e' ana
> pedro tem 10 anos e seu responsavel e' ana
POO Avançado - Copyright Tecgraf PUC-Rio
20
Input Stream
• A class istream é usada para ler e interpretar
uma sequência de bytes
• Suporta entrada formatada e não formatada
• Instância da classe istream definidas em
<iostream>
– cin: representa a entrada padrão (stdin)
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
21
Formatação da entrada em istream
• O operador >> é usado para formatar os
dados obtidos de um istream
– Ex: uma sequência de caracteres lida é formatada
como um valor numérico, booleano, etc.
istream&
istream&
istream&
istream&
istream&
istream&
istream&
istream&
istream&
istream&
istream&
08/09/10
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
operator>>
(bool& val );
(short& val );
(unsigned short& val );
(int& val );
(unsigned int& val );
(long& val );
(unsigned long& val );
(float& val );
(double& val );
(long double& val );
(void*& val );
POO Avançado - Copyright Tecgraf PUC-Rio
22
O operador >> para entrada
formatada
• Não lê espaço em branco
• Retorna 0 quando encontra EOF
• Suporte a manipuladores de entrada
skipws
Ignora espaço em branco
noskipws
Não ignora espaço em branco
boolalpha
Lê valor booleano com a notação alfanumérica (ex: true e
false)
noboolapha
Lâ valor booleano com a notação 0 e 1
dec
Lê valor numérico decimal
hex
Lê valor numérico hexadecimal
ws
Extrai os espaços em branco
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
23
Exemplo de entrada formatada
int n;
char str[10];
bool b;
cout << "Entre um numero decimal: ";
cin >> n;
cout << "O numero digitado e': " << n << endl;
cout << "Entre um numero hexadecimal: ";
cin >> hex >> n;
// manipulador
cout << "O numero decimal equivalente e': " << n << endl;
cout << "Entre uma palavra: ";
cin.width (10);
// maximo
cin >> str;
cout << "Os primeiros 9 caracteres da palavra sao: "
<< str << endl;
cout << "Entre com true ou false: ";
cin >> boolalpha >> b;
cout << "O valor booleano digitado e': " << b << endl;
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
24
Entrada não formatada
• Funções get, getline e read
– Lêem caracteres
– O espaço em branco é lido como um caractere qualquer
– Retorna EOF se o final de arquivo é encontrado (ctr-z
ou ctrl-d, dependendo do sistema)
•
int get();
Extrai e retorna um caractere do stream de entrada (cast para int)
int character;
cout << "Entre com uma frase seguida de EOF:" << endl;
while ( ( character = cin.get() ) != EOF ) {
cout.put( character );
}
cout << "\nEOF no sistema: " << character << endl;
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
25
Funções get
• Não removem o delimitador do stream de entrada
• Colocam o terminador null ('\0') no final
– istream& get ( char& c );
Extrai um caractere do stream de entrada e coloca no
parâmetro c
– istream& get (char* s, streamsize n );
Extrai caracteres do stream de entrada e guarda no array
apontado pelo parâmetro s. Os caracteres são lidos até a
quantidade de n-1 caracteres ou até o delimitador '\n' ser
encontrado.
– istream& get (char* s, streamsize n, char
delim );
O mesmo que o anterior, exceto que o delimitador é
especificado no parâmetro delim.
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
26
Funções getline
• Removem o delimitador do stream de entrada
• Colocam o terminador null ('\0') no final
– istream& getline (char* s, streamsize n );
Extrai caracteres do stream de entrada e guarda no array
apontado pelo parâmetro s. Os caracteres são lidos até a
quantidade de n-1 caracteres ou até o delimitador '\n' ser
encontrado.
– istream& getline (char* s, streamsize n, char
delim );
O mesmo que o anterior, exceto que o delimitador é
especificado no parâmetro delim.
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
27
Exemplo de leitura com getline
#include <iostream>
using namespace std;
int main () {
char name[256], title[256];
cout << "Entre com seu nome: ";
cin.getline (name,256);
cout << "Entre com seu filme favorito: ";
cin.getline (title,256);
cout << "O filme favorito de " << name
<< " e' " << title << endl;
return 0;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
28
Função read
•
stream& read ( char* s, streamsize n );
Lê um bloco de dados de tamanho n e guarda no parâmetro s. Se
EOF for encontrado, guarda os caracteres lidos antes. Não coloca
o terminador null ao final do bloco.
int main()
{
char buf[10];
cin.read(buf,10);
cout << "Lidos " << cin.gcount() << " caracteres: "
<< buf << endl;
return 0;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
29
Outras funções membros de istream
•
istream& ignore(streamsize n=1, int delim=EOF)
Extrai caracteres do stream de entrada e não guarda em lugar
algum
•
istream& putback ( char c );
Coloca um caractere no stream de entrada
•
int peek ( )
Lê e retorna o próximo caractere sem removê-lo de stream de
entrada
•
streamsize
gcount ( ) const;
Retorna o número de caracteres lidos na última leitura não
formatada
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
30
Outros exemplos de leitura de dados
char first, last;
cout << "Entre com seu primeiro e ultimo nomes: ";
first=cin.get();
cin.ignore(256,' ');
last=cin.get();
cout << "Suas iniciais sao " << first << last << endl;
> Entre com seu primeiro e ultimo nomes: Joao Pedro
> Suas iniciais sao JP
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
31
Input em tipos definidos pelo usuário
• A classe pode definir o operador >> seguindo
o mesmo padrão dos tipos primitivos
• Se for lido algum dado não previsto:
– A implementação do operador pode alterar os
bits de erro
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
32
Input em tipos definidos pelo usuário
istream& operator>>(istream &is, person &p) {
char c;
char name[256]; int age=10;
is >> c;
if (c=='(') {
is.getline (name, 256, ',');
is >> age >> c;
if (c!=')') is.clear (ios_base::badbit);
} else {
is.putback (c);
is >> name;
}
p = person(age, name);
return is;
}
int main() {
person aPerson;
cout << "Entre com uma pessoa: " << endl;
cin >> aPerson;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
33
Estado de Stream
• Todo stream (istream ou ostream) possui um
estado associado
• Erros e condições anormais são tratados
alterando e testando esse estado, indicados
por bits de estado
– iostate rdstate ( ) const;
08/09/10
eofbit
EOF lido de um inputstream
failbit
A última operação de leitura falhou
badbit
Erro devido a uma falha na leitura ou na escrita
goodbit
Sem erro. Corresponde ao valor zero.
POO Avançado - Copyright Tecgraf PUC-Rio
34
Estado de Stream
• Ao invés de testar usando operações sobre
bits, as seguintes funções estão disponíveis:
– bool eof ( ) const;
– bool fail ( ) const;
– bool bad ( ) const;
– bool good ( ) const;
• Para alterar o estado de um stream
– void clear ( iostate state = goodbit );
– Ex: cin.clear( ios::failbit )
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
35
Exemplo dos estados de streams
cout << "Antes de entrar com um valor invalido:" << endl
<< "cin.rdstate(): " << cin.rdstate() << endl
<< "cin.eof(): " << cin.eof() << endl
<< "cin.fail(): " << cin.fail() << endl
<< "cin.bad(): " << cin.bad() << endl
<< "cin.good(): " << cin.good() << endl
<< "Espera um inteiro, porem, entre com um caractere: ";
cin >> integerValue;
cout << endl;
cout << "Apos a entrada invalida:" << endl
<< "cin.rdstate(): " << cin.rdstate() << endl
<< "cin.eof(): " << cin.eof() << endl
<< "cin.fail(): " << cin.fail() << endl
<< "cin.bad(): " << cin.bad() << endl
<< "cin.good(): " << cin.good() << endl;
cin.clear(); // limpa o estado do stream
cout << endl;
cout << "Apos cin.clear()" << endl
<< "cin.fail(): " << cin.fail() << endl
<< "cin.good(): " << cin.good() << endl;
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
36
File Streams
• As classes ifstream, ofstream e fstream são
usadas para manipulação de arquivos como
sequência de caracteres, de forma similar ao
que foi visto até aqui
– ifstream é um istream
– ofstream é um ostream
– fstream é um iostream que herda de istream e de
ostream, servindo, portanto, para arquivos de
leitura e escrita
• Estão definidas em <fstream>
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
37
Exemplo de cópia de um arquivo
#include <iostream>
#include <fstream>
using namespace std;
void error (const char* p, const char* p2="") {
cerr << p << ' ' << p2 << endl;
exit(1);
}
int main(int argc, char* argv[]) {
if (argc!=3) error("Numero de argumentos invalido");
ifstream from (argv[1]);
if (!from) error("Nao pode abrir o arquivo de entrada");
ofstream to (argv[2]);
if (!to) error("Nao pode abrir o arquivo de saida");
char c;
while (from.get(c)) to.put(c);
if (!from.eof() || !to)
error("Houve erro na copia do arquivo");
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
38
Abrindo arquivos
• Os construtores das classes abrem o arquivo
quando recebem o nome como parâmetro
• A função membro open também pode ser
usada para abrir arquivo
– void open ( const char * filename,
ios_base::openmode mode = ios_base::in );
• Parâmetro opcional para o modo de abertura
app
(append) Coloca o cursor no final do arquivo após operações output
ate
(at end) Abre com a cursor no final do arquivo
binary
(binary) Binário ao invés de texto
in
(input) Permite operações de entrada
out
(output) Permite operações de saída
trunc
(truncate) Apaga o conteúdo corrente
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
39
Fechando arquivos
• Por default, arquivos são fechados nos seus
destrutores
• Opcionalmente, arquivos podem ser fechados
usado a função close()
• Pode ser útil para fechar um arquivo antes de
terminar o escopo do bloco onde ele é usado
int main () {
ifstream infile;
infile.open ("test.txt", ifstream::in);
while (infile.good())
cout << infile.get();
infile.close();
return 0;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
40
Processando String como Stream
• Objetos da classe stringstream permitem
que strings possam ser manipulados da
mesma forma que streams
– stringstream: permite entrada e saída
– istringstream: permite apenas entrada
– ostringstream: permite apenas saída
• Classes definidas no arquivo <sstream>
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
41
Exemplo de StringStream
#include <iostream>
#include <sstream>
using namespace std;
void word_per_line (const string& s) {
istringstream ist(s);
string w;
while (ist>>w) cout << w << endl;
}
int main() {
word_per_line ("Voce acha c++ dificil?");
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
42
Buffering
• Streams de entrada e saída usam buffer para
armazenar os dados antes de descarregá-los
no dispositivo associado ao stream
– A classe Streambuf definida em <streambuf>
usada como tipo genérico para buffers de
streams
• Unbuffered I/O são streams cujo streambuf
descarrega imediatamente cada caractere,
sem acumulá-los para uma operação de
transferência mais eficiente
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
43
Streambuf
• Podem ser compartilhados entre diferentes
streams
– streams não podem ser copiados e nem
atribuídos, porém um stringbuf pode
int main(int argc, char* argv[]) {
ofstream fil;
if (argc > 1) {
fil.open(argv[1]);
cout = fil; // Erro de compilação!!!
}
cout << "Ola mundo!" << endl;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
44
Redirecionando o cout usando
streambuf
#include <iostream>
#include <fstream>
using namespace std;
Repare que, enviar dados para o cout,
passou a ser o mesmo que enviar dados
para o arquivo “test.txt”
int main () {
streambuf *psbuf, *backup;
ofstream filestr;
filestr.open ("test.txt");
backup = cout.rdbuf(); // ponteiro para o buffer do cout
psbuf = filestr.rdbuf(); // ponteiro para o buffer do file
cout.rdbuf(psbuf);
cout << "Escrevendo esse conteudo no arquivo";
cout.rdbuf(backup);
filestr.close();
return 0;
}
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
45
Compartilhando o streambuf
Note que file1 e file2 compartilham o
mesmo buffer. Portanto, enviar dados
para um ou para o outro, escreve no
mesmo arquivo. As propriedades de
formatação de cada stream, no entanto,
são preservadas.
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
ofstream file1("test1.txt");
ostream file2(file1.rdbuf());
file1.setf(ios_base::fixed, ios_base::floatfield);
file1.precision(5);
file2.setf(ios_base::scientific, ios_base::floatfield);
file2.precision(3);
file1 << setw(10) << 47.11 << '\n';
file2 << setw(10) << 47.11 << '\n';
}
> cat test1.txt
47.11000
4.711e+01
08/09/10
POO Avançado - Copyright Tecgraf PUC-Rio
46

Documentos relacionados