programação em c++ pimenta rodrigues pedro pereira manuela sousa entrada e saída de dados...
TRANSCRIPT
Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Entrada e saída de dados
Programação em C++
Entrada e saída de dados 3 - 2 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
• As acções de entrada e saída de dados não fazem parte da linguagem C++.
• Por forma a uniformizar as primitivas através das quais um programa invoca as acções de I/O (entrada e saída de dados) a linguagem C++ virtualiza todos os dispositivos envolvidos nestas acções como objectos streams.
• A linguagem C++ dispõe de uma biblioteca de classes stream, cujas declarações se situam nos ficheiros iostream.h, iomanip.h e fstream.h, satisfazendo ao paradigma da Programação Orientada por Objectos.
Biblioteca de Streams do C++
Entrada e saída de dados 3 - 3 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Biblioteca de Streams do C++• Todos os dispositivos lógicos (streams) são
semelhantes em comportamento, e bastante independentes dos dispositivos reais.
• Distinguem-se dois tipos de streams - streams para texto e streams para palavras binárias
• Um stream, associa-se a um periférico realizando uma operação abertura (open), e desassocia-se dele com uma operação de fecho (close).
Entrada e saída de dados 3 - 4 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
• As streams cin e cout tornam-se a interface entre o programa e o utilizador, para interactuar com o keyboard e com o ecrã.
• O stream cin é criado automaticamente quando se inclui o ficheiro header <iostream.h> ficando associado ao keyboard do terminal.
• O stream cout é criado automaticamente quando se inclui o ficheiro header <iostream.h> ficando associado ao ecrã do terminal
cin e cout
extern istream cin;extern ostream cout;
Entrada e saída de dados 3 - 5 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Saída de dados - operador << (1)
27x
stream cout
'2''7''\n'...
bufferconverter o inteiro 27
nos caracteres '2','7' ecolocá-los no buffer
colocar o caracter"mudança de linha
no buffer".
27 _
Fazer flush ao buffer,ou seja, escrever todoo conteudo do buffer
no ecrã
int x = 27; ... cout << x; // operação 1 cout << endl; // operações 2 e 3
1
23
Entrada e saída de dados 3 - 6 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Saída de dados - operador << (2)
O operador insersor <<, retorna uma referência para o ostream sobre o qual operou, pelo que se podem concatenar inserções numa mesma expressão.
void main() int i= 10, double d= 3.1456;
cout << "i =" << i << ", d=" << d << endl;
/* Equivalente a: cout << "i =”; // insere a string "i =" cout << i; // insere o valor inteiro de i cout << ", d=" ; // insere a string cout << d; // insere o valor real de d cout << endl; // insere o caracteres ‘\r\n’ e //faz flush do buffer. */}
Entrada e saída de dados 3 - 7 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
27x
stream cin
' ''0''0''2''7'' '' ''x''p''t''o''\n'
buffer
ignorou-se o espaço inicial econverteram-se os digitos
'0','0','2','7' para o valorinteiro 27
int x; char y[7]; ... cin >> x; // operação 2 cin >> y; // operação 3
2
1
Quando foi digitado o<return> preencheu-se o
buffer com a linha completa
y 'x' 'p' 't' 'o' 0 ? ?
ignorou-se os espaços e leu-seas letras 'x','p','t','o' para o arraycolocando um <zero> a seguir
ao 'o' para terminar a string.
3
Digitou-se:" 0027 xpto<Return>"
Entrada de dados - operador >> (1)
Entrada e saída de dados 3 - 8 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Entrada de dados - operador >> (2)
• O operador extractor >>,toma como operando esquerdo um istream e como operando direito a variável a afectar com o valor extraído do istream.
• O operando direito pode ser qualquer dos tipos intrínseco do C++, pois em <iostream.h> estão definidos várias versões do operador insersor .
• Por omissão, salta espaços em branco (como definido na função isspace() em <ctype.h>), lendo seguidamente os caracteres adequados ao tipo de objecto que vai ser afectado.
void main() { char c; int i; char str[10]; float f;
cin >> c >> i >> f >> str;
/* Equivalente a: cin >> c; // extrai um carácter // diferente de separador. cin >> i; // extrai um valor inteiro. cin >>f; // extrai um valor real. cin >> str;// extrai uma palavra. */
cout << "c = " << c << endl << "i = " << i << endl << "f = ” << f << endl << "str = " << str << endl;}
Entrada e saída de dados 3 - 9 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
istream & get(char &ch); // lê um único caracter;// Ex . - Copiar uma linha do standard input para o standard output#include <iostream.h>void main() { char ch; do { cin.get(ch); cout << ch; } while (ch!= '\n');}
Métodos de entrada e saída e não formatada
istream::putback(char ch); // Torna a repor o caracter no buffer de input// Ex. - Consumir espaços em branco#include <iostream.h>#include <ctype.h>istream& eatwhite( istream& is ) { char c; while (is.get(c)) { if ( ! isspace (c) ) { is.putback(c); // Colocar no buffer o caracter diferente de separador break; } } return is;}
get
putback
Entrada e saída de dados 3 - 10 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Métodos de entrada e saída e não formatada
istream::getline( char *line, int size, char terminator)/*Os caracteres são extraídos até que uma das seguintes condições se verifiquem:- size-1 caracteres sejam lidos;- não existam mais caracteres para ler (EOF - fim de ficheiro);- o caracter lido seja o caracter terminador. Neste caso, o caracter é lido mas não é inserido no vector line.No fim da sequência de caracteres é sempre inserido o caracter nulo (‘\0’), logo a dimensão máxima da string é size-1 caracteres .
Ex . - Digitar uma linha terminada por 'p'*/#include <iostream.h>void main() { char line[100]; cout << " Digite uma linha terminado por 'p'" << endl; cin.getline( line, 100, 'p' );// 'p' é caracter terminador cout << line;}
getline
Entrada e saída de dados 3 - 11 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Funções para filtrar caracteresAs funções seguintes, reconhecem tipos de caracteres retornando true ou false conforme o caracter testado satisfizer ou não a condição da função evocada.
int isdigit(char) // '0' .. '9'int islower(char) // 'a' .. 'z’int isupper(char) // 'A' .. 'Z' int isalpha(char) // islower() | isupper() int isalnum(char) // isalpha() | isdigit()int isxdigit(char) // '0' .. '9' 'a' .. 'f' 'A' .. 'F'int isascii(char) // 0 .. 0x7F int iscntrl(char) //caracteres de controlint isgraph(char) //isalpha() | isdigit() | ispunct ()int isprint(char) // printable: ascii entre ' ' e '~'int ispunct(char) // pontuaçãoint isspace(char) // ' ' '\t' CR LF
Entrada e saída de dados 3 - 12 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
ManipuladoresManipulador In Out Definição
endl v Mudar de linha e flush do ostream.
ends v Inserir ‘\0’ para terminar string.
flush v Esvaziar (flush) o buffer do ostream.
dec v v Conversão para base decimal.
hex v v Conversão para base hexadecimal.
oct v v Conversão para base octal.
ws v Eliminar caracteres separadores.
setbase(int b) v v Fixar a base de conversão em b.
resetiosflags(long b) v v Desactivar bit-vector flags de acordo com b. Ver
setiosflags(long b) v v Activar os bit-vector flags de acordo com b. Ver
setfill(int f) v Definir o carácter de preenchimento de espaços docampo com (char)f
setprecision(int n) v Situar em n dígitos a precisão de um floating-point.
setw(int n) v v Colocar em n caracteres a largura do campo.
Existem manipuladores para streams, de entrada (mudam o formato das extracções) e/ou de saída (mudam o formato das inserções)
Os manipuladores estão declarados em <iomanip.h>. Eis os mais comuns :
Entrada e saída de dados 3 - 13 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Manipuladores - exemplo
#include<iostream.h>#include<iomanip.h>#include<conio.h>void main() { clrscr(); int i=123; double d=12345.6789; char *s= "blabla"; cout << setw(10) << s << endl << i << endl << setw(10) << i << endl << d << endl << setw(15) << setfill('*') << d << endl << setw(13) << setfill(' ') << setprecision(3) << setiosflags(ios::left) << d << s << endl;}
Qual o output deste programa :
blabla123 12312345.6789*****12345.678912345.679 blabla
Entrada e saída de dados 3 - 14 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Flags de formatação de um stream
Flag In Out Definição
ios::skipws v Salta espaços em branco no input.
ios::left v Espaços à esquerda.
ios::right v Espaços à direita.
ios::internal v Espaços entre o sinal e o valor.
ios::dec v v Conversão para base decimal.
ios::hex v v Conversão para base hexadecimal.
ios::oct v v Conversão para base octal.
ios::fixed v Usa a notação 123.45 para os floating point.
ios::scientific v Usa a notação 1.2345E2 para os floating point.
ios::showbase v Força a escrita da base.
ios::showpoint v Força a escrita do ponto (floating point).
ios:: showpos v Adiciona o '+' nos inteiros positivos.
ios::uppercase v Escreve em maiúsculas quando a base éhexadecimal.
Entrada e saída de dados 3 - 15 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Acesso a ficheiros• Podem ser definidos objectos associados a ficheiros, e
passar a interactuar com esses objectos com os mesmos operadores, métodos e manipuladores que se utilizam para cin e cout.
• Existem vários objectos que podemos criar para ter acesso a ficheiros:– ifstream - quando queremos abrir um ficheiro para leitura.– ofstream - quando queremos abrir um ficheiro para escrtita.– fstream - quando se deseja que o ficheiro possa ser lido e escrito.
• Para criar qualquer um dos tipos de objectos anteriores, teremos de explicitamente proceder aos vários passos da definição, que nos são ocultos no caso de cin e cout.
Entrada e saída de dados 3 - 16 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Métodos open() e close() sobre streams
O método close() garante: que toda a informação situada no buffer é transferida para ficheiro em disco, e que as estruturas de dados inerentes à organização do disco sejam devidamente actualizadas.
is.close(); // Fechar o ficheiro de input
os.close(); // Fechar o ficheiro de output
#include <fstream.h>ifstream is; // ficheiro de input// Abrir o ficheiro para ler.is.open(“c:\mensage\text1.doc”);
ifstream is(“c:\mensage\text1.doc”);
Equivale a:
Acesso a um ficheiro para leitura.
#include <fstream.h>ofstream os; // ficheiro de output// Abrir o ficheiro para escrita.os.open(“c:\mensage\text2.doc”);
ofstream os(“c:\mensage\text2.doc”);
Acesso a um ficheiro para escrita.
Equivale a:
Entrada e saída de dados 3 - 17 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Teste de erro na abertura de um fstream
No caso de uma acção de open() sobre um fstream não ser bem conseguida, por qualquer motivo, esse facto pode ser reconhecido em programa, testando o objecto stream como valor lógico.
ifstream input("file.txt") ;if (!input) { cout << "Sarilhos " << endl; exit(0);}
#include<fstream.h>#include<iostream.h>#include <stdlib.h>void main(){ char ch; ifstream f1("file.in"); if (!f1) { // Teste ao estado da fstream input cout << "Cannot open 'file.in' for input" << endl; exit(0); } ofstream f2("file.out"); if (!f2) { // Teste ao estado da fstream de output cout << "Cannot open 'file.out' for output" << endl; exit(0); } while ( f1.get(ch) ) f2.put(ch); f1.close(); f2.close(); cin.get();}
Cópia do ficheiro “file.in” para “file.out”
Entrada e saída de dados 3 - 18 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
• Ao contrário de objectos do tipo ifstream e ofstream, que têm modos de acesso pré- estabelecidos, os objectos do tipo fstream, podem ter acesso para escrita, para leitura, ou ambos.• A iniciação de um objecto fstream pode ser efectuada com um único parâmetro string, mas também podemos explicitar num segundo parâmetro a especificação de modos alternativos
de acesso.
Modos de acesso de um fstream
M o d e b i t A c ç ã o
i o s : : a p p A p p e n d d a t a - E s c r e v e n o f im d o f ic h e ir o
i o s : : a t e P o s ic io n a - s e n o f im d o f ic h e ir o in ic ia lm e n t e
i o s : : i n A b r e o f ic h e ir o p a r a le i t u r a
i o s : : o u t A b r e o f ic h e ir o p a r a e s c r i t a
i o s : : b i n a r y A b r e o f ic h e ir o e m m o d o b in á r io
i o s : : t r u n c D e s p r e z a o a n t e r io r c o n t e ú d o d o f ic h e ir o .
i o s : : n o c r e a t e F a lh a a a c ç ã o s e n ã o e x is t i r o f ic h e ir o
i o s : : n o r e p l a c e S e o f ic h e ir o e x is t ir , f a lh a a b e r t u r a ( o p e n ) p a r a s a í d a , am e n o s q u e a t e o u a p p e s t e j a m a c t iv a s .
3-10
Entrada e saída de dados 3 - 19 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Restrições dos fstreams
• Todos os operadores, funções e manipuladores usados para de cin e cout, podem, sem nenhuma alteração sintáctica, ser aplicados a ficheiros abertos em modo de texto para leitura ou para escrita.
• Os ficheiros prestam-se a acções que não são comuns utilizar sobre o teclado e ecrã. Nomeadamente o acesso aleatório ou o posicionamento especificado.
• Os operadores insersores e extractores estão vocacionadas para ficheiros de texto.
• Para ficheiros binários são usados os métodos get(), put(), read() e write()
Entrada e saída de dados 3 - 20 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Modos de abertura - exemplos (1)
ifstream in ("t1.doc"); // fstream in("t1.doc", ios::in);ofstream out("t2.doc"); // fstrteam out(“t2.doc”, ios::out | ios::trunc);
Abertura para leitura com ifstreams e para escrita com ofstreams
ifstream in ("t1", ios::binary);ofstream out("t2", ios::binary);
Abertura de ficheiros em modo binário
Por omissão do segundo paraâmetro, um ifstream é aberto no modo leitura de texto e um ofstream é aberto no modo escrita de texto
fstream inOut("t1.doc", ios:in | ios::out); // textofstream inOut("t1.doc", ios:in | ios::out | ios::binary);// binário
Abertura para leitura e escrita com fstreams
Entrada e saída de dados 3 - 21 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Modos de abertura - exemplos (2)
// fich. texto com escrita no fimofstream out("t1.doc", ios:app);
// fich. binário com escrita no fimofstream out("t1.doc", ios:app | ios::binary);
// fich. texto com posicionamento no fim e com possibilidade de acesso directoofstream out ("t1.doc", ios:ate);
// fich. binário com posicionamento no fim e com possibilidade de acesso directoofstream out ("t1.doc", ios:ate | ios::binary);
Abertura para escrita com posicionamento no fim do
ficheiro.
Entrada e saída de dados 3 - 22 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Método write()
#include <fstream.h>struct Date { int mo, da, yr; }void main() { Date dt = { 6, 10, 91 }; ofstream tfile( "date.dat" , ios::binary ); tfile.write( (char *) &dt, sizeof dt );}
• Insere no stream n caracteres. Se o ficheiro for de texto virtualiza o caracter '\n' , num par ('\r', '\n').
• É vocacionada para registar estruturas de dados em ficheiros binários, embora possa ser usada em ostream na generalidade.
ostream& write(const char* ptr, int n);ostream& write(const signed char* ptr, int n);ostream& write(const unsigned char* ptr,int n);
write
Armazenar uma data em ficheiro
Entrada e saída de dados 3 - 23 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Método read()read
O método read() é vocacionada para a leitura de estruturas de dados de ficheiros binários, embora possa ser usada noutro tipo de istreams.
ostream& read(char* ptr, int n);ostream& read(signed char* ptr, int n);ostream& read(unsigned char* ptr, int n);
#include <iostream.h>#include <fstream.h>void main() { struct { double salary; char name[23]; } employee; ifstream is( "payroll", ios::binary | ios::nocreate ); if( is ) { // ios::operator void*() is.read( (char *) &employee, sizeof( employee ) ); cout << employee.name << ' ' << employee.salary << endl; } else cout << "ERROR: Cannot open file 'payroll'." << endl;}
Teste do método read()
Entrada e saída de dados 3 - 24 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Acesso aleatório a ficheiros
fstream farray("Array", ios:: in | ios::out| ios::binary);
Declarado um fstream associado a um dado ficheiro, com um modo de acesso (segundo parâmetro) simultaneamente para entrada e saída:
• O ficheiro criado pode ser utilizado para virtualizar em disco um array com acesso por índice para ler e escrever em qualquer dos seus elementos.
• O método seekg(long n), posiciona no byte n (a contar do inicio do ficheiro), o que permite alterar o acesso ao ficheiro para acções de leitura (get).
• O método seekp(long n), posiciona no byte n para escrita(put), o que permite alterar o acesso ao ficheiro para acções de escrita.
Entrada e saída de dados 3 - 25 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Inversão de um ficheiro de inteiros
#include <fstream.h>#include <iostream.h>#include <iomanip.h>fstream farray("intArray", ios:: in | ios::out| ios::binary);const int NUMINT = 100;void main() { for (int i = 0; i < NUMINT; ++i) farray.write((char *) &i, sizeof(int));// escreve for (int begin = 0, end = NUMINT -1; begin < NUMINT/2; ++begin, --end ) { int auxBegin, auxEnd; farray.seekg(begin * sizeof(int)); // lê o inteiro cuja posição é begin farray.read((char *) &auxBegin, sizeof(int)); farray.seekg(end * sizeof(int)); // lê o inteiro cuja posicao é end farray.read((char *) &auxEnd, sizeof(int)); farray.seekp(begin * sizeof(int)); // escreve o valor do auxEnd inteiro na posição begin farray.write((char *) &auxEnd, sizeof(int)); farray.seekp(end * sizeof(int)); // escreve o valor do auxBegin inteiro na posicao end farray.write((char *) &auxBegin, sizeof(int)); }}
Entrada e saída de dados 3 - 26 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Hierarquia iostream
Entrada e saída de dados 3 - 27 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Acções de I/O directas sobre o terminal
• As primitivas de I/O comunicam directamente com o dispositivo físico (contrariamente às streams).
• Estas primitivas não constam nas bibliotecas standard do C++, no entanto são necessárias em algumas aplicações :
– Recolha directa de caracteres sem edição de linha, ou seja, sem ser necessário aguardar a actuação da tecla <ENTER> ou <RETURN> para que o carácter fique disponível.
– Recolha de caracteres com ou sem eco no ecrã.– Obter informação do teclado acerca da existência ou não de caracteres já disponíveis
para recolha, permitindo realizar outras operações enquanto os caracteres não estejam disponíveis.
• Em PCs as declarações das acções directas sobre o terminal (consola) estão disponíveis no ficheiro <conio.h>
Entrada e saída de dados 3 - 28 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
int getch( )
#include <iostream.h>#include <ctype.h>#include <conio.h>
void main() { unsigned char ch; // unsigned para codigo > 127 do { cout << "\nPrima uma tecla (terminar '*')" << endl; ch = (unsigned char)getch(); // Testar se o primeiro código é de acção. O primeiro // código pode ser 0 ou 224. if( ch==0 || ch==224 ) cout << "Tecla de accao com codigo " << (unsigned int) getch() << endl; else { cout << "A tecla nao e de accao"; if ( isprint(ch) ) cout << ", corresponde ao caracter " << ch; cout << ", tem o codigo " << (unsigned) ch << endl; } } while ( ch != '*' );}
Detecção de teclas de acção
Função getch()
• Recolhe caracteres do teclado sem a actuação da tecla <ENTER> e sem eco
• Devolve o código da tecla premida
• As teclas de acção (F1 a F12, Insert, Home, , , , , etc.), geram dois códigos:
1º: Sem significado (0, 224, etc).
2º: Código específico da tecla. Para recolher informação sobre estas teclas é necessário evocar a função por duas vezes.
Entrada e saída de dados 3 - 29 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Função getche()
• Idêntica à função getch(), só que faz eco do caracter premido.
#include <iostream.h>#include <conio.h>
void main() { int ch; do { cout << "Prima uma tecla alfanumerica - " << flush; ch = getche(); cout << "\nTecla com o codigo ASCII " << ch << endl; } while ( ch != '*' );}
getche( ) Ler teclas e escrever o correspondente código.
Entrada e saída de dados 3 - 30 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Função putch()putch(char ch)
• Coloca directamente na consola o caracter cujo código é ch.
#include <conio.h>#include <ctype.h>void main() { char ch; do { putch( toupper( ch = (char) getch() ) ); if (ch == '\r') putch('\n'); } while (ch != '*');}
Ler teclas e ecoar em maiúsculas.
Entrada e saída de dados 3 - 31 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Função kbhit()Int kbhit ( )
• Testa se uma tecla foi ou não actuada. #include <iostream.h>
#include <conio.h>#include <ctype.h>void main(){ do { while( ! kbhit() ) putch('.'); getch(); //Consumir carácter de paragem. cout << "\nQuer continuar (S/N)? " << flush; //Recolher 'S' ou 'N' . } while( toupper(getch()) == 'S' );}
Faz uma espera activa, escrevendo caracteres ‘.’ enquanto não for premida uma tecla.
Entrada e saída de dados 3 - 32 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa
Manipulação de stringsO ficheiro <string.h> dispõe da declaração dos protótipos das
funções de manipulação de strings.
• int strlen(char *str);– Recebe uma string como parâmetro e devolve a sua dimensão.
• char *strcpy( char *dst, const char *src );
– Copia a string src para a string dst e devolve um apontador para a string dst.
• int strcmp( const char *str1, const char *str2 );
– Compara str1 com str2 e devolve : 0 se str1 = str2; < 0 se str1 < str2; > 0 str1 > str2.
• char *strcat( char *dst, const char *src );
– Concatena a string src, à string dst e devolve um apontador para a string dst.
• char *strstr( const char *str, const char *str1 );
– Procura a ocorrência de str1 em str. Devolve um apontador para a 1ª ocorrência de str1 em str, ou NULL caso não exista.
• char *strchr( const char *str,int c);
– Procura a ocorrência do caracter c str. Devolve um apontador para a 1ª ocorrência c em str, ou NULL caso não exista.