Entrada y salida
A vueltas con el flujo (cin cout), vamos a ver un uso mas extendido del habitual.
De paso conoceremos algunas de las trampas que nos esperan con los flujos, sobre todo por el tema de buffers.
Veamos este ejemplo comentado
/**
* Flujos.cpp
* Programa para mostrar el uso de flujos
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o Flujos Flujos.cpp
*/

#include <iostream.h>

// Disponemos de varios flujos:
// cin : para la entrada de distintis tipos de datos (std input)
// cout : para la salida de distintos tipos de datos (std output)
// cer: para la salida de errores (std error)
// clo: para la salida de errores y redireccion a ficheros tipo log

// cin utiliza buffers y nos podemos llevar sorpresas al recoger datos
// si el usuario no los mete bien. Por ejemplo si se pide una palabra y se meten
// dos, la siguiente vez que se pida otro dato se tomara el que se habia metido!
// lo podemos evitar con cin.ignore

// Funcion principal
int main () {

unsigned int i;
char nombre_apellidos[25];
char linea[80];
int entero;
char caracter;

// ATENCION
// hay que tener cuidado con los strings. prueba a meter nombre y apellido
// y veras que el string solo se llena hasta el primer espacio en blanco,
// o incluso para a la siguiente variable i y el programa casca.
cout << "Mete tu nombre y tu apellido resalao: " << endl;
cin >> nombre_apellidos;
cout << "Tu nombre y apellidos: " << nombre_apellidos << endl;

// con esta llamada evitamos que se tome en cuenta las sobras
cin.ignore(255,'
');

// Entrada multiple!
cout << "Mete una palabra y un numero entero" << endl;
cin >> nombre_apellidos >> entero;
cout << "El texto: " << nombre_apellidos  << " y el entero: " << entero << endl;
// explicacion: >> es un operador que se puede sobrecargar como hemos visto
// anteriormente: la expresion cin >> nombre_apellidos devuelve otro objeto iostream
// y se podria reescribir asi: (cin >> nombre_apellidos) >> entero;


// cin.get(string,tamaño) para recoger string completos
cout << " Mete un string largo con espacios. " << endl;
cin.getline(linea,80);
cout << "resultado: " << linea << endl;
// hay veces que puede interesar ignorar un numero de caracteres hasta llegar al final
// de la linea, para eso podemos usar la funcion cin.ignore(70,'
'); en lugar de

// podemos usar cualquier caracter de terminacion que nos interese.

// no hay que olvidar que cin es un buffer. Que pasa si solo queremos leer un caracter
// sin tener que 'sacarlo' del buffer? podemos usar cin.peek() y si queremos meter
// un caracter podemos usar cin.putback('.') -meteria un . en el buffer de cin

// cin.get() tomando un unico caracter. Si metemos mas imprimira todos
// puede usarse parametrizado: cin.get(caracter)
cout << "Vete metiendo caracteres. termina con un ." << endl;
while ( (caracter = cin.get()) != EOF) {
    if ( cin.peek() == '.' ) {
        cout << "nos vamos" << endl;
        break;
    }
    cout << caracter;
}
cin.ignore(255,'
');
cin >> i;
}
En este otro se habla mas de cout
/**
* FlujosOut.cpp
* Programa para mostrar el uso de flujos de SALIDA
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o FlujosOut FlujosOut.cpp
*/

#include <iostream.h>

// cout  tambien utiliza buffers y nos podemos llevar sorpresas al recoger datos
// aunque si queremos tirar de la cadena ejecutamos: cout << flush;

// Funcion principal
int main () {

unsigned int i;
char nombre_apellidos[25];
char linea[80];
int entero;
char caracter;
char frase[] = "Clatu verata nictu
";


// si en cin teniamos get aqui tenemos: put
// mandamos un saludo
cout.put('K').put('a').put('i').put('x').put('o').put('
');
// vamos a mostrar una linea:
entero = strlen(frase);
// con esto la mostramos entera
cout.write(frase,entero);
// con esto... no
cout.write(frase, (entero-5));
cout << " ahora con formato: " << endl;

// vamos a ponerla con cierto formato: width y fill
cout.width(30); // esto mete espacios en blanco equivalente = setw(30)
cout << frase << endl;

cout.width(50); // esto vuelve a meter espacios
cout.fill('>'); // y esto RELLENA los ESPACIOS
cout << frase << endl;

// Estableciendo el estado de cout con setf
// alineacion: setf(ios::left)  y setf(ios::right)
// hay mas, para investigar: ios::showbase, ios::internal, etc...
cout.setf(ios::right);
entero = 666;
// podemos alterar la base con dec, oct y hex
cout << "entero hexadecimal alineado a la derecha: " <<  hex << entero << endl;


cin >> i;
}
Ficheros en c++ Oh si, podemos manejar ficheros de entrada/salida con las clases mas std. veamos unos ejemplos, metidos dentro de un objeto. Es bastante mejorable.
/**
* Fichero.hpp
* Clase que define el objeto Fichero, un objeto que sirve gestionar un fichero
*
* Pello Xabier Altadill Izura
*
*/

#include <iostream.h>
#include <fstream.h>  // atencion hay que incluir esto

enum tipo_fichero { ENTRADA, SALIDA, APPEND };

class Fichero {
    public:
        Fichero();
        Fichero(char *nombre, tipo_fichero tipo);
        ~Fichero();
        Fichero(Fichero const &);

        char *getNombre() const { return this->nombre;}

        // operaciones sobre ficheros
        int cerrar () const; // cierra el fichero
        char  leer() const; // lee del fichero
        void escribir (char linea[255]) const; // escribe linea

    private:
        // esta funcion decide que tipo de fichero iniciar
        void inicializaFichero();
        tipo_fichero tipo;
        char *nombre;
        ofstream *saliente;
        ifstream *entrante;
};
Y su implementacion.
/**
* Fichero.cpp
* Programa que implementa la clase Fichero
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o Fichero Fichero.cpp
*
*/

#include "Fichero.hpp"

        // Constructor
        Fichero::Fichero(): nombre("test.txt"), tipo(ENTRADA) {
                inicializaFichero();
                cout << "Fichero construido." << endl;
        }

        // Constructor
        Fichero::Fichero(char *nombre, tipo_fichero tipo) {
                this->nombre = nombre;
                this->tipo = tipo;
                inicializaFichero();
                cout << "Fichero construido con nombre: " << nombre << endl;
        }

        // Destructor
        Fichero::~Fichero() {
                cout << "Fichero destruido." << endl;
        }

        // Constructor copia
        Fichero::Fichero(Fichero const & original) {
                nombre = new char;
                nombre = original.nombre;
        }

        // cierra el fichero
        int Fichero::cerrar () const {
                if (this->tipo == 0) {
                    entrante->close();
                } else {
                    saliente->close();
                }
                return 0;
        }

        // lee linea del fichero
        char Fichero::leer () const {
                return entrante->get();
        }

        // escribir sobre el fichero
        void Fichero::escribir (char linea[255]) const {
                saliente->write(linea,255);
        }

        // esta funcion decide que tipo de fichero iniciar
        void Fichero::inicializaFichero() {
                switch (this->tipo) {
                   case 0  : cout << "tipo ENTRADA" << endl;
                             entrante = new ifstream(this->nombre);
                             break;
                   case 1  : cout << "tipo SALIDA" << endl;
                             saliente = new ofstream(this->nombre);
                             break;
                   case 2  : cout << "tipo APPEND" << endl;
                             saliente = new ofstream(this->nombre,ios::app);
                             break;
                   default : cout << "nada" << endl;
                             break;
                }

        }

// funcion principal, en la que de paso vemos
// PARAMETROS de linea de comandos
int main (int argc, char **argv) {
int i;
char temp;
char linea[255];
// vamos a revisar los argumentos que se han pasado al programa
for (i=0; i<argc; i++) {
           cout << "argumento (" << i << "): " << argv[i] << endl;
}

Fichero fichero = Fichero("prueba.txt",APPEND);

cout << "escribe algo par añadir al fichero: ";
cin.getline(linea,255);
cout << "has puesto: " << linea << endl;
fichero.escribir(linea);
fichero.cerrar();

// leyendo de forma directa. Leemos el parametro que hayamos pasado
ifstream leer("prueba.txt");

// abrimos el fichero
leer.open("prueba.txt");

// recorremos el fichero y mostramos contenido
while ( leer.get(temp) ) { // esto indica el final
cout << temp;
}

// cerramos el fichero
leer.close();

return 0;
}