// Programación en C++ para Ingenieros, Ed. Thomson Paraninfo, 2006
// Capítulo 10: Ficheros




// Inclusión de las librerías
#include <iostream>
#include <fstream>

using namespace std;



// Prototipos
void fusionarFicheros(ifstream& f1, ifstream& f2, ofstream& fResu);
template <class T>
void abreFichero(T& fich, const char* nombre);
void vuelca(ifstream& f1, ofstream& fDest);


int main(void)
{
    char nombre1[100], nombre2[100];


    cout << "Introduce el nombre del primer fichero a fusionar: ";
    cin >> nombre1;
    ifstream f1;
    abreFichero(f1, nombre1);


    cout << "Introduce el nombre del segundo fichero a fusionar: ";
    cin >> nombre2;
    ifstream f2;
    abreFichero(f2, nombre2);


    char nombreDest[100];
    cout << "Introduce el nombre del fichero destino: ";
    cin >> nombreDest;
    ofstream fDest;
     abreFichero(fDest, nombreDest);

    fusionarFicheros(f1, f2, fDest);
    f1.close();
    f2.close();
    fDest.close();

    return 0;
}


// Funcion generica para abrir un fichero de
// fomra que se puede usar tanto para ficheros
// de entrada (ifstream) como de salida (ofstream)
template <class T>
void abreFichero(T& fich, const char* nombre)
{
    fich.open(nombre);
    if ( !fich )
    {
        cout << "No puedo abrir el fichero " << nombre << endl;
        exit( 1 );
    }
}



void fusionarFicheros(ifstream& f1, ifstream& f2,
                      ofstream& fDest)
{
    int numF1, numF2;

    f1 >> numF1;
    f2 >> numF2;


    while (!f1.eof() && !f2.eof())
    {
        if (numF1 < numF2)
        {
            fDest << numF1 << " ";
            f1 >> numF1;
        }
        else
        {
            fDest << numF2 << " ";
            f2 >> numF2;
        }
    }

    if (f1.eof())
    {
        fDest << numF2 << " ";
        vuelca(f2, fDest);
    }
    else
    {
        fDest << numF1 << " ";
        vuelca(f1, fDest);
    }
}

void vuelca(ifstream& f1, ofstream& fDest)
{
    int elem;

    while (f1 >> elem)
        fDest << elem << " ";

}