C++
Home

Entrada e saída com streams em C++
Funções membro peek, putback e ignore de Istream
E/S não-formatada com read, gcount e write
Precisão em ponto flutuante ( precision, setprecision )
Criando Manipuladores
Estados de formato do stream
Estados de Erro do stream
Vinculando um stream de saída a um stream de entrada


Entrada e Saída com Streams em C++

A entrada e saida ( E/S ) ocorre em streams em C++;
Stream é simplesmente uma sequência de bytes. O Trabalho de e/s é mover bytes de dispositivos para a memória e vice-versa, de maneira confiável.

Em E/S no estilo de C, o programador precisa especificar qual o tipo que está trabalhando, em C++ o tipo é determinado automaticamente.

Como segue no exemplo, na impressão de um char

char *string = "teste";
cout << "Valor da string: " << string;

* Importante, sempre que você quiser mostrar o endereço de um ponteiro, você deve usar a coerção para void*
cout << "Valor do ponteiro" << static_cast< void * >( string );

-> Para saída de um unico caracter, utilize put.
Put pode ser encadeado, put('a').put('b').
Put imprime expressões equivalentes aos caracteres ASCII, put(65) == "A"

Exemplo:

cout.put( 'A' ).

-> Operador de Extração de stream, utilize cin
cin pode ser encadeado, cin >> x >> y >> a; Neste caso, a leitura irá acontecer digitando os numeros com espaço, 10 20 30, por exemplo.

-> Função membro Get e Getline
A função get sem parâmetros fornece como entrada um caracter do stream designado e retorna esse valor como chamada da função . Ela retorna EOF quando o fim do arquivo é encontrado.

Exemplo:
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{

  char c;

  cout << "Digite várias letras" << endl;

  while ( ( c = cin.get() ) != EOF )
  {
    cout.put( c );
  }

  cout << "EOF é igual a:" << c << endl;

  system("pause");

  return 0;
}

A segunda versão de get recebe 2 parametros.
A string onde será armazenada e o tamanho necessário.
Ele retorna 0 quando fim do arquivo, caso contrário retorna uma referência para istream.

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{

  const int tamanho = 80;
  char buffer[tamanho];

  cout << "Didite: "<< endl;
  cin.get( buffer, tamanho );

  cout << buffer;

  system("pause");

 return 0;
}

* Lendo desta forma, ele aceita espaços.

A terceira versão de get aceita 3 parâmetros, um array de caracteres, um limite de tamanho, e um delimitador ( com valor default '\n' ). Esta versão lê caracteres até o valor de tamanho, ou até que um caracter delimitador seje digitado.

Neste caso, ao invez de usar a terceira função de get, usamos a função membro getline, que le o delimitador, mais não o guarda no array.


Funções membro peek, putback e ignore de Istream

A função ignore ignora um número especifico de caracteres ( o default é 1 ).

A função membro putback coloca o último caractere lido de um stream de entrada por um get de volta naquele stream. Esta função é útil para aplicativos que varrem streams de entrada procurando um campo com um caracter inicial específico.

A função membro peek retorna o próximo caractere de um stream de entrada, mas não remove o caractere do stream.


E/S não-formatada com read, gcount e write

As funções write e read recebem como entrada, ou envia para saída, um certo número de bytes para ou de um array de caracteres da memoria.
Exemplo:

char buffer[] = "Coisa loca, loca mesmo";
cout.write( buffer, 10);

envia para a saída os 10 primeiros bytes de buffer, inclusive caracteres nulos.

Na função read, se o número de caracteres lidos é menor que o especificado, failbit é ligado.

A função gcount informa o número de caracteres lidos pela última operação de entrada.

Exemplo:

// enquanto ele nao completa os 20 caracteres, ele não mostra... porém mostra tudo, incluse enter

#include <iostream>

int main()
{

  const int SIZE = 80;
  char buffer[ SIZE ];

  std::cout << "Digite uma fraze:" << std::endl;
  std::cin.read( buffer, 20 );

  std::cout << "A fraze digitada eh:" << std::endl;
  std::cout.write( buffer, std::cin.gcount() );

  std::cout << std::endl;

  return 0;
}


Precisão em ponto flutuante ( precision, setprecision )

Controlando a precisão de números em ponto flutuante, o número de dígitos à direita do ponto decimal, usando ou o manipulador de stream setprecision ou a função precision. Uma chamada a qualquer um desses, define a saida de todas as operações subsequentes.

A função precision sem tamanho retorna a definição atual.

Exemplo:

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

#include <iomanip>

using std::ios;
using std::setprecision;
using std::setiosflags;

#include <cmath>

int main()
{

  // precision
  double root2 = sqrt( 2.0 );
  int places;

  std::cout << setiosflags( ios::fixed )
  << " Raiz quadrada de 2 com precisões de 0 a 9 " << endl;

  for ( places = 0; places <= 9; places++ )
  { 
    cout.precision( places );
    cout << root2 << std::endl;
  }

  cout << "Precisao iniciada pelo manipulador setprecision " << endl;

  for ( places = 0; places <= 9; places++ )
  {
    cout << setprecision( places ) << root2 << std::endl;
  }

  return 0;
}


Criando Manipuladores

Dica: Podemos tambem criar nossos proprios manipuladores de stream parametrizados ( consulte o manual para isso )

Segue um exemplo com ostream:

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

std::ostream& endLine( std::ostream &saida )
{
   // flush libera buffer
   return saida << "\n " << std::flush;
}

int main()
{
   cout << "FIM de LINHA" << endLine;

    return 0;
}


Estados de formato do stream

Vários indicadores de formatos indicam os tipos de formatação a serem executados durante as operações de E/S com streams.
As funções membro setf, unsetf e flags controlam as definições destes indicadores.

ios::skipws
Ignora espaços em branco em uma stream de entrada
ios::left
Justifica à esquerda a saída em um campo
ios::right
Justifica à direita
ios::internal
Indica que o sinal de um número deve ser alinha do esquerda em um campo e a magnitude do número deve ser alinhada a direita nesse mesmo campo
ios::dec
Trata números em valores decimais
ios::oct
Especifica que inteiros devem ser tratados como valores octais ( base 8 ).
ios::hex
Especifica que os inteiros devem ser tratados como valores hexadecimais ( base 16 )
ios::showbase
Especifica que a base de um número deve ser mostrada à frente do número na saída ( um 0 à esquerda oara octais. um 0x ou 0X para hexadecimais ).
ios::showpoint
Especifica que um número flutuante deve ser mostrado na saida com um ponto decimal. É usado normalmente ios::fixed para garantir que um certo número de digitos a direita do ponto decimal )
ios::uppercase
Especifica letras maiúsculas
ios::showpos
Mostra o sinal na frente de um número ( + e - )
ios::scientific
Mostra saida de números em notação cientifica

O programador pode usar o operador sobre streams "|" para combinar opções. Isto retorna um valor Long



Estados de Erro do stream

O eofbit é ligado para um stream de entrada quando é encontrado o fim do arquivo.

Um programa pode usar a função cin.eof para determinar se o fim de arquivo foi encontrado em um stream depois de uma tentativa de extrair dados do fim do stream.

O failbit é ligado para um stream quando um erro de formato acontece no stream.
Quando tentamos jogar letras para um int, as informações não são perdidas. Quando ocorre um erro como este, fail informa se uma operação de stream falhou.

O badbit é ligado quando em um stream acontece um erro que resulta na perca de dados.

O goodbit é ligado quando bad, fail e eof retornam false.

A função membro rdstate retorna o estado de erro de stream.

cin.clear(); // liga goodbit

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

int main()
{
  int x;

  cout << "Antes de entrada com problema " << endl;
  cout << "cin.rdstate(): " << cin.rdstate();
  cout << "\ncin.eof(): " << cin.eof();
  cout << "\ncin.fail(): " << cin.fail();
  cout << "\ncin.bad(): " << cin.bad();
  cout << "\ncin.good(): " << cin.good();

  cout << "Digite um valor " << endl;
  cin >> x; // digite A

  cout << "Apos entrada com problema " << endl;
  cout << "cin.rdstate(): " << cin.rdstate();
  cout << "\ncin.eof(): " << cin.eof();
  cout << "\ncin.fail(): " << cin.fail();
  cout << "\ncin.bad(): " << cin.bad();
  cout << "\ncin.good(): " << cin.good();

  cin.clear();

  cout << "Apos cin clear " << endl;
  cout << "\ncin.fail(): " << cin.fail();
  cout << "\ncin.good(): " << cin.good();

  return 0;
}


Vinculando um stream de saída a um stream de entrada

C++ oferece a função membro tie para sincronizar ( amarrar ) um istream a um ostream, para garantir que a saída apareça antes de sua subsequente entrada.

A chamada

cin.tie( &cout );

Amarra cout a cin. Na realidade, chamar tie é redundante. Por que C++ executa automaticamente.

tie( 0 ) dessamara