Hey guys, I need help with another one of those I/O File coding. I am super clueless and this is what I have so far:

/*Write a program that merges the numbers in two files and writes all the
numbers into a third file. Your program takes input from two different files and writes
its output to a third file. Each input file contains a list of numbers of type int in sorted
order from the smallest to the largest. After the program is run, the output file will
contain all the numbers in the two input files in one longer list in sorted order from
smallest to largest. Your program should define a function that is called with the two
input-file streams and the output-file stream as three arguments.*/


#include <iostream>
#include <fstream>

using namespace std;

int main()
{
int num1, num2;

ifstream inputFile;
ifstream inputFile2;
inputFile.open ("input1.txt");
inputFile2.open("input2.txt");
ofstream outputFile;
outputFile.open("output.txt");

inputFile >> num1;
inputFile2 >> num2;
while(inputFile.eof() && inputFile2.eof())
{
    if (num1 < num2)
    {
        outputFile << num1;
        inputFile >> num1;
    }
    else
    {       
        outputFile << num2;
        inputFile2 >> num2;
    }

}

inputFile.close();
inputFile2.close();
outputFile.close();

return 0;
}


input1.txt

1 2 3 4 4 5 6 7 7 7 8 9 10 20



input2.txt

11 12 13 14 14 15 15 15 16 17 18 19 20

Please help, no arrays yet. I am only up to functions so nothing too fancy as I am a beginner.

You appear to have most of it solved, just some little details to figure out.
while(inputFile.eof() && inputFile2.eof())
Assuming both files opened successfully, this line will keep any useful work from ever happening. eof( ) returns false every time until the end of file has actually been reached (attempt to read past end of file.) So, when using eof( ), you need to use the not operator (!), like:
while(! inputFile.eof() && ! inputFile2.eof())

Now you'll get into the loop, which looks like it will do the job, unitl one file runs out. After the loop ends, you need to be sure to write the values remaining in whichever file still has data.

Your desired main function (with the merge file function) could look something like this:

int main()
{

    ifstream fin1("input1.txt");
    ifstream fin2("input2.txt");
    ofstream fout("output.txt");

    if( fin1 && fin2 && fout )
    {
        mergeFiles( fin1, fin2, fout );
        fout.close();
        fin2.close();
        fin1.close();
    }
    else cout << "There was some problem opening files ...\n";
}

Edited 2 Years Ago by David W

Don't forget to handle 'all' the cases ...
including if either of the input files is empty.

This can actually be a little tricky to handle.

You may like, while debugging, to count all the inputs and outputs, to ensure the totals match.

If you would like to see an example, (with debugging code that counts input and output), no problem :)

Edited 2 Years Ago by David W

The example that I mentioned that you would like to see ...

// input1.txt
/*
1 2 3 4 4 5 6 7 7 7 8 9 10 20 25
*/
// input2.txt
/*
1 2 5 5 9 9 10 11 12 13 14 14 15 15 15 16 17 18 19 20 21
*/

void mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout )
{
    int i1, i2, countIn = 0, countOut = 0;

    if( fin1 >> i1 ) ++ countIn;

    // Now firstly ... handle case of ... if empty file 1 ... //
    if( fin1 ) // i.e. count == 1
    {
        // Then ... handle case of ... if empty file 2 ... //
        if( fin2 >> i2 )
        {
            ++ countIn;

            while( fin1 && fin2 )
            {
                if( i1 <= i2 )
                {
                    fout << i1 << ' ';
                    ++countOut;
                    if( !(fin1 >> i1) )
                    {
                        fout << i2 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
                else
                {
                    fout << i2 << ' ';
                    ++countOut;
                    if( !(fin2 >> i2) )
                    {
                        fout << i1 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
            }
        }
        else
        {
            fout << i1 << ' ';  // Do NOT forget to write this //
            ++countOut;
        }
    }


    // check end conditions ... at most below, one line gets executed ... //
    while( fin1 >> i1 ) { fout << i1 << ' '; ++countIn; ++countOut; }
    while( fin2 >> i2 ) { fout << i2 << ' '; ++countIn; ++countOut; }

    // 'in' and 'out' counts *should* match if all 'in' was 'out' ok ... //
    cout << "countIn = " << countIn << endl;
    cout << "countOut = " << countOut << endl;
}

While there is nothign at all wrong with doing the heavy lifting yourself, C++ comes with a nice standard library; if you read all the numbers from both files, and as you read them insert them into a std::set, when you're finished reading, the set is ordered and contains no duplicates, ready for you to simply write out the set from start to finish.

Edited 2 Years Ago by Moschops

Yes ... using the STL set (or multiset) is sure a whole lot easier to code and use ... if your files will both fit into (available) memory :)

Edited 2 Years Ago by David W

I just remembered a previous example I did some time ago, with a simpler code ...

Take a look and you may see why I prefer this simpler (and more symetric) code.

// mergeTwoSortedFiles.cpp // 

// Note this example (safe) reads the files 
// *as strings
// *one number (one string) on each line ...
// *then converts each C++ string to a C string ...
// *then gets the int value of that C string using atoi

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> // re. atoi

using namespace std;


const char* FILE_O = "file_o.txt"; // the output file //
const char* FILE_A = "file_a.txt";
/*
1
4
6
9
11
99
101
*/
const char* FILE_B = "file_b.txt";
/*
2
4
7
9
10
79
100
123
124
125
*/


void showFile( const char* fname )
{
    ifstream fin( fname );
    string line;
    int n = 0;
    while( getline( fin, line ) )
    {
        cout << " " << line;
        ++n;
    }
    cout << " n = " << n << endl;
    // fin.close(); // not really needed here ... since ...
                    // will be close when falls out of scope //
}


int main()
{
    ifstream finA ( FILE_A );
    ifstream finB ( FILE_B );
    ofstream fout ( FILE_O );

    if( finA && finB && fout )
    {
        string lineA, lineB;
        getline(finA, lineA);
        getline(finB, lineB);

        while( finA && finB )
        {
            if( atoi(lineA.c_str()) <= atoi(lineB.c_str()) )
            {
                fout << lineA << endl;
                getline(finA, lineA);
            }
            else
            {
                fout << lineB << endl;
                getline(finB, lineB);
            }
        }

        // test end conditions ...
        if( finA )
        {
            fout << lineA << endl;
            while( getline(finA, lineA) )
                fout << lineA << endl;
        }
        else if( finB )
        {
            fout << lineB << endl;
            while( getline(finB, lineB) )
                fout << lineB << endl;
        }

        fout.close();
        finB.close();
        finA.close();
    }
    else cout << "Error! There was a problem opening files ... \n";

    showFile( FILE_A );
    showFile( FILE_B );
    showFile( FILE_O );

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    cin.get(); // keep 'Window' open until 'Enter' key is pressed ...
}

Edited 2 Years Ago by David W

Sorry I haven't replyed back, had a bio exam lab test. Anyways, this is what I tried to do, and I'm kinda lost David.

#include <iostream>
#include <fstream>

using namespace std;
void mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout );

int main()
{
int num1, num2;

ifstream inputFile;
ifstream inputFile2;
inputFile.open ("input1.txt");
inputFile2.open("input2.txt");
ofstream outputFile;
outputFile.open("output.txt");

//inputFile >> num1;
//inputFile2 >> num2;
//while(inputFile.eof() && inputFile2.eof())
//{
//    if (num1 < num2)
//    {
//        outputFile << num1;
//        inputFile >> num1;
//    }
//    else
//    {       
//        outputFile << num2;
//        inputFile2 >> num2;
//    }
//
//}

mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout );

inputFile.close();
inputFile2.close();
outputFile.close();

system ("PAUSE");
return 0;
}

void mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout )
{
    int i1, i2, countIn = 0, countOut = 0;
    if( fin1 >> i1 ) ++ countIn;
    // Now firstly ... handle case of ... if empty file 1 ... //
    if( fin1 ) // i.e. count == 1
    {
        // Then ... handle case of ... if empty file 2 ... //
        if( fin2 >> i2 )
        {
            ++ countIn;
            while( fin1 && fin2 )
            {
                if( i1 <= i2 )
                {
                    fout << i1 << ' ';
                    ++countOut;
                    if( !(fin1 >> i1) )
                    {
                        fout << i2 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
                else
                {
                    fout << i2 << ' ';
                    ++countOut;
                    if( !(fin2 >> i2) )
                    {
                        fout << i1 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
            }
        }
        else
        {
            fout << i1 << ' ';  // Do NOT forget to write this //
            ++countOut;
        }
    }
    // check end conditions ... at most below, one line gets executed ... //
    while( fin1 >> i1 ) { fout << i1 << ' '; ++countIn; ++countOut; }
    while( fin2 >> i2 ) { fout << i2 << ' '; ++countIn; ++countOut; }
    // 'in' and 'out' counts *should* match if all 'in' was 'out' ok ... //
    cout << "countIn = " << countIn << endl;
    cout << "countOut = " << countOut << endl;
}

The code isn't working. I'm not sure if I am doing it properly. But, my instructor said I was on the right track though with this.

Time to learn to debug. Pick some likely places in your code, and add code to output what's going on to the screen. You'll find somewhere where somethihng isn't being read properly, or written properly, or the numbers are in the wrong order, or something that isn't right.

I don't have debugging for the microsoft visual studio express. the Ultimate version isn't compatible with windows 8 :/

You can use cout to debug. Just output parts that are questionable or you are not sure what the value is. You don't need to actually step through a debugger to debug code.

Edited 2 Years Ago by NathanOliver

add code to output what's going on to the screen

For example,
cout << "Read in value from file: " << i2 << endl;

try this fix:

// mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout ); // <== you had this WRONG line //

mergeFiles( inputFile, inputFile2, outputFile );

After you have the above working ... see added code and better comments here ... (but note the simpler and more symetric code demo'd above ... the 2nd example)

#include <iostream>
#include <iomanip> // re. setw
#include <fstream>

using namespace std;


void mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout );

void showFile( const char* fname );


int main()
{
    ifstream fin1( "input1.txt" );
    ifstream fin2( "input2.txt" );
    ofstream fout( "output.txt" );

    mergeFiles( fin1, fin2, fout );

    fout.close(); // ensure flushed ... //

    showFile( "input1.txt" );
    showFile( "input2.txt" );
    showFile( "output.txt" );

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    cin.get();
    return 0;
}


void mergeFiles( ifstream& fin1, ifstream& fin2, ofstream& fout )
{
    int i1, i2, countIn = 0, countOut = 0;
    if( fin1 >> i1 ) ++ countIn;

    // Can firstly handle case of ...  if empty file 1 //
    if( fin1 ) // i.e. count == 1
    {
        // Then can handle case of ... if empty file 2 //
        if( fin2 >> i2 )
        {
            ++ countIn;
            while( fin1 && fin2 )
            {
                if( i1 <= i2 )
                {
                    fout << i1 << ' ';
                    ++countOut;
                    if( !(fin1 >> i1) )
                    {
                        fout << i2 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
                else
                {
                    fout << i2 << ' ';
                    ++countOut;
                    if( !(fin2 >> i2) )
                    {
                        fout << i1 << ' ';
                        ++countOut;
                        //break; // handled by while ... above //
                    }
                    else ++countIn;
                }
            }
        }
        else
        {
            fout << i1 << ' ';  // Do NOT forget to write this //
            ++countOut;
        }
    }

    // check end conditions ... at most below, one line gets executed ...
    // Note: this also handles cases of empty file 1 and/or empty file 2

    while( fin1 >> i1 ) { fout << i1 << ' '; ++countIn; ++countOut; }
    while( fin2 >> i2 ) { fout << i2 << ' '; ++countIn; ++countOut; }

    // 'in' and 'out' counts *should* match if all 'in' was 'out' ok  //
    cout << "countIn = " << countIn << endl;
    cout << "countOut = " << countOut << endl;
}

void showFile( const char* fname )
{
    ifstream fin( fname );
    if( fin )
    {
        cout << "\nShowing numbers in file "
             << fname << " ...\n";
        int tmp;
        while( fin >> tmp ) cout << setw( 7 )<< tmp << ' ';
        fin.close();
        cout << endl;
    }
    else cout << "\nThere was a problem opening file "
              << fname << endl;
}
This article has been dead for over six months. Start a new discussion instead.