Entrada e saída de dados

32
Programação em C++ Pimenta Rodrigues Pedro Pereira Manuela Sousa Entrada e saída de dados Programação em C++

description

Programação em C++. Entrada e saída de dados. Biblioteca de Streams do C++. As acções de entrada e saída de dados não fazem parte da linguagem C++. - PowerPoint PPT Presentation

Transcript of Entrada e saída de dados

Page 1: Entrada e saída de dados

Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa

Entrada e saída de dados

Programação em C++

Page 2: Entrada e saída de dados

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++

Page 3: Entrada e saída de dados

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).

Page 4: Entrada e saída de dados

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;

Page 5: Entrada e saída de dados

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

Page 6: Entrada e saída de dados

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. */}

Page 7: Entrada e saída de dados

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)

Page 8: Entrada e saída de dados

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;}

Page 9: Entrada e saída de dados

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');}

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;}

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

Page 10: Entrada e saída de dados

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;}

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

Page 11: Entrada e saída de dados

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

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

Page 12: Entrada e saída de dados

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 :

Page 13: Entrada e saída de dados

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

Page 14: Entrada e saída de dados

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.

Page 15: Entrada e saída de dados

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.

Page 16: Entrada e saída de dados

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.

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 inputis.close(); // Fechar o ficheiro de input

os.close(); // Fechar o ficheiro de outputos.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”);

#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”);ifstream is(“c:\mensage\text1.doc”);

Equivale a:Equivale a:

Acesso a um ficheiro para leitura.

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”);

#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”);ofstream os(“c:\mensage\text2.doc”);

Acesso a um ficheiro para escrita.

Acesso a um ficheiro para escrita.

Equivale a:Equivale a:

Page 17: Entrada e saída de dados

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.

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);}

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();}

#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”

Cópia do ficheiro “file.in” para “file.out”

Page 18: Entrada e saída de dados

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 i r , 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

Page 19: Entrada e saída de dados

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()

Page 20: Entrada e saída de dados

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);

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

Abertura para leitura com ifstreams e para escrita com ofstreams

ifstream in ("t1", ios::binary);ofstream out("t2", ios::binary);

ifstream in ("t1", ios::binary);ofstream out("t2", ios::binary);

Abertura de ficheiros em modo binário

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

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

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

Abertura para leitura e escrita com fstreams

Page 21: Entrada e saída de dados

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);

// 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.

Abertura para escrita com posicionamento no fim do

ficheiro.

Page 22: Entrada e saída de dados

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 );

}

#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);

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

Armazenar uma data em ficheiro

Page 23: Entrada e saída de dados

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);

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;

}

#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()Teste do método read()

Page 24: Entrada e saída de dados

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);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:

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.

Page 25: Entrada e saída de dados

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));

}

}

#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));

}

}

Page 26: Entrada e saída de dados

Entrada e saída de dados 3 - 26 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa

Hierarquia iostream

Page 27: Entrada e saída de dados

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>

Page 28: Entrada e saída de dados

Entrada e saída de dados 3 - 28 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa

int getch( )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 != '*' );}

#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çãoDetecçã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.

Page 29: Entrada e saída de dados

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 != '*' );}

#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( )getche( ) Ler teclas e escrever o correspondente código.

Ler teclas e escrever o correspondente código.

Page 30: Entrada e saída de dados

Entrada e saída de dados 3 - 30 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa

Função putch()

putch(char ch)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 != '*');}

#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.Ler teclas e ecoar em maiúsculas.

Page 31: Entrada e saída de dados

Entrada e saída de dados 3 - 31 Programação em C++Pimenta RodriguesPedro PereiraManuela Sousa

Função kbhit()

Int 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' );}

#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.

Faz uma espera activa, escrevendo caracteres ‘.’ enquanto não for premida uma tecla.

Page 32: Entrada e saída de dados

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.

O 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.