Laboratório de Programação II - Turma 490
Horários: 2AB e 4CD

Prof. Márcio Sarroglia Pinho
Página diagramada pelo Estagiário de Docência Rafael Rieder

Entrada/Saída com Streams

Objeto "cout" << Operador de Extração Entrada de Strings
<< Operador de Inserção E/S Segura quanto ao tipo Exemplos
Objeto "cin"
Manipuladores de Streams Material Adicional

Objeto "cout'"

O objeto cout representa o stream de saída no C++. Este stream é uma espécie de seqüência (fluxo) de dados a serem impressos na tela.
Para realizar a impressão, usa-se o "operador de inserção" que "insere" dados dentro do stream.



<< Operador de Inserção

operador << sobrecarregado executa a saída (imprime na tela) com streams em C++.  O objeto cout é usado em conjunto com ele para a impressão de dados.

#include <iostream>
using namespace std;
int main()
{
  cout << "Imprimindo o famoso HELLO WORLD!!!\n";

  // imprimindo uma linha usando múltiplos comandos
  cout << "Teste com ";
  cout << "dois couts\n";

  // usando o manipulador endl
  // endl gera um caractere nova linha, e também descarrega o buffer de saída

  cout << "Escrevendo uma linha..." << endl;

  cout << "Mais uma vez...\n";
  cout << flush;    // agora apenas esvaziando o buffer de saída, sem gerar nova linha

  return 0;
}

<< sempre retorna uma referência ao objeto cout. Desta forma, é possível encadear vários cout, permitindo uma combinação de constantes e variáveis, como mostra o exemplo abaixo:

int a = 10;
int b = 12;
// imprime uma string e o resultado da soma entre as variáveis a e b
cout << "Encadeando saídas: Somandos dois números " << a + b << endl;

A saída de caracteres também pode ser feita sem o uso do operador de inserção <<. Para isto, usa-se a função membro put, que retorna uma referência para o objeto cout. Exemplos:

cout.put('caractere');    // fazendo a saída de um único caractere
cout.put('caractere').put('\n');    // fazendo a saída encadeada


Objeto "cin"

O objeto cin representa o stream de entrada no C++. Ele realiza a leitura de um seqüência de dados, sem espaços e sem tabulações, vindas do teclado.
Para coletar estes dados armazenados, usa-se o "operador de extração" que "extrai" dados do stream.



>> Operador de Extração

operador >> sobrecarregado executa a entrada com streams em C++, usando o comando cin para aquisição de dados. Variáveis podem ser usadas para o armazenamento das informações.

#include <iostream>
using namespace std;
int main()
{
  int Num1;
  int Num2;
  cout << "Lendo o primeiro número...: ";
  cin >> Num1;
  cout << endl;
  cout << "Lendo o segundo número....: ";
  cin >> Num2;
  cout << endl;

  return 0;
}

Da mesma forma que o operador de inserção, >> sempre retorna uma referência ao objeto cin, permitindo o encadeamento de vários cin. Exemplo:

float c;
float d;
cin >> c >> d;    // entra com um float, pressiona <ENTER>, entra com outro float, pressiona <ENTER>

Outras peculiaridades usando o operador de extração:

while(cin >> dado)    // repete enquanto o usuário não digitar fim de arquivo (Ctrl+Z ou Ctrl+D)

cin.eof();            // devolve 1 (verdadeiro) se chegou ao fim do arquivo

char c;
c = cin.get();
cin.get(vet, n, '\n');
char nome[100];
cin >> nome;            // lê até o 1º espaço em branco apenas
cin.get(nome, 100);     // lê até o 99º caractere ou <ENTER>
cin.get(nome, 100, 'x');
/* get sempre insere um NULL no final da seqüência lida.
   O delimitador não é retirado da entrada. Isto faz com que a próxima leitura devova este caractere (no caso, uma linha será devolvida. */

cin.getline(nome, TAM);    // remove o delimitador do buffer automaticamente

cin.putback();        // recoloca o último caractere lido de volta no buffer

E/S segura quanto ao tipo

Quando dados inesperados são processados pelos operadores << e >>, vários indicadores de erros podem ser ativados para indicar se houve sucesso ou falha em uma operação de E/S.
O exemplo abaixo apresenta alguns deles:


int dado;
cin.eof();         // retorna verdadeio ser o fim do arquivo foi encontrado
cin >> dado;       // lê um inteiro
if(cin.bad()) {   
// houve uma falha na leitura
  // ...
}
if(cin.fail()) {   // dado digitado incompatível com o dado esperado
  // ...
}
if(cin.fail()) {   // estado da stream está OK
  // ...
}

ou usando

ios::eofbit
ios::badbit
ios::failbit
ios::goodbit
cin.clear();      // reseta o estado de stream, ativando "goodbit"

Manipuladores de streams

Executam tarefas de formatação, por meio de diferentes recursos. Alguns deles estão abaixo destacados:

Base do stream de inteiros

#include <iomanip>
#include <iostream>
using namespace std;
// ...
cin >> n;
cout << hex << n << endl            // apresenta n em hexadecimal
     << oct << n << endl            // apresenta n em octadecimal
     << setbase(10) << n << endl;   // apresenta n na base 10
// ...

Precisão em ponto flutuante:


double PI = 3.14159265;

cout.precision(5);    // define a precisão
cout << setiosflags (ios::fixed) << f << endl;
cout << PI;           // imprime PI com 5 casas decimais
ou
cout << setiosflags (ios::fixed) << setprecision(5) << PI;    // define e imprime PI com 5 casas decimais

Para retornar ao formato de impressão padrão:

  cout << setiosflags (ios::scientific);
  cout << f << endl;

Largura de campo:

Para definir a largura da impressão de uma variável usa-se o setw(n), onde n é o número de caracteres desejado para a impressão desta variável.
Note que o setw só afeta a próxima variáveldo cout.

int caixas = 45;
cout << "Número de caixas: " << setw(10) << caixas << endl;

Alinhamento da impressão

É possível alinhar os dados impressos tanto à esquerda quanto à direita, com os manipuladores left e right.

cout  << right <<  10;
cout  << left <<  10;


Entrada de Strings

Em determinadas ocasiões, deseja-se coletar dados que contenham strings com tabulações, espaços em branco e/ou novas linhas. Frases são exemplos onde este tipo de situação ocorre. No entanto, o operador >> sobrecarregado ignora tais caracteres.

Para englobar essas situações, C++ oferece o uso da função-membro getline. Esta função remove o delimitador do stream (isto é, lê o caractere e o descarta) e armazena o mesmo em uma variável definida pelo usuário.

Abaixo, um exemplo de sua utilização.
 
#include <iostream>
using namespace std;
int main()
{
  const TAM = 80;
  char guarda[TAM];
  cout << "Digite uma frase com espaços: " << endl;
  cin.getline(guarda, TAM);
  cout << "A frase digitada é: \n" << guarda << endl;
  return 0;
}

Exemplos

Entrada de string com cin
Entrada de string com getline


Material Adicional

C++ IO/Flags
Problemas com o uso de getline no Visual C++ 6.0