// File: inclass18.cpp
// This program reads in integers from a file into an array, prints
// them out on the screen, sorts the array and writes the values back
// out to a file.
//
// Input (file): integers
// Output (screen and file): integers in sorted order
// ----------------------------------------------------------------------
// Class: CS 210                     Instructor: Dr. Deborah Hwang
// Assignment: Programming Exercise for 3/21/06
// Programmer(s): <fill in your name(s)>

#include <fstream>     // ifstream, ofstream
#include <iostream>    // cin, cout, <<, >>, endl
#include <iomanip>     // setw
#include <cstdlib>     // exit
using namespace std;

// Function prototypes
void InteractiveOpen (ifstream & theIFStream);
void InteractiveOpen (ofstream & theOFStream);
void ReadArray (double theArray[], int & numElements, int capacity);
void PrintArray (const double theArray[], int numElements);
void WriteArray (const double theArray[], int numElements);
void Swap (double & first, double & second);

// Problem constants
const int CAPACITY = 40;      // Capacity of the array
const int MAX_FILE_NAME = 80; // Maximum number of characters in file name

int main ()
{
   // Local data
   double numbers[CAPACITY];    // Array of real numbers
   int count;                   // Actual number of elements in array

   // Greet the user
   cout << "This program reads in a list of real numbers from a file, prints\n"
        << "them out, sorts them, and writes them back to a file.\n";

   // Read in numbers from a file
   ReadArray (numbers, count, CAPACITY);

   // Print the numbers
   cout << "\nThe numbers read from the file are:\n";
   PrintArray (numbers, count);

   // Sort the array (to be written for the exercise)

   // Print the numbers again
   cout << "\nThe numbers after being sorted are:\n";
   PrintArray (numbers, count);

   // Write the numbers to a file
   WriteArray (numbers, count);

   return 0;
}  // end main


// Function: InteractiveOpen (for input file streams)
// Asks the user for a file name and connects the file to theIFStream
void InteractiveOpen (ifstream & theIFStream)  
                      // RECEIVED & PASSED BACK: input file stream
{
   char inputFileName[MAX_FILE_NAME];  // input file name

   cout << "\nEnter the name of the input file: ";
   cin >> inputFileName;

   theIFStream.open(inputFileName);

   if (!theIFStream.is_open())
   {
      cerr << "\n***InteractiveOpen(): unable to open "
           << inputFileName << endl;
      exit(1);
   }  // end if
}  // end InteractiveOpen


// Function: InteractiveOpen (for output file streams)
// Asks the user for a file name and connects the file to theOFStream
void InteractiveOpen (ofstream & theOFStream)
                      // RECEIVED & PASSED BACK: output file stream
{
   char outputFileName[MAX_FILE_NAME];  // output file name

   cout << "\nEnter the name of the output file: ";
   cin >> outputFileName;

   theOFStream.open(outputFileName);

   if (!theOFStream.is_open())
   {
      cerr << "\n***InteractiveOpen(): unable to open "
           << outputFileName << endl;
      exit(1);
   }  // end if
}  // end InteractiveOpen


// Function: ReadArray
// This function fills an array with data items from a file.
void ReadArray (double theArray[],   // PASSED BACK: array to be filled
                int & numElements,   // PASSED BACK: number of elements filled
                int capacity)        // RECEIVED:  maximum number of elements
{
   ifstream inStream;  // input file stream
   double value;       // input variable

   InteractiveOpen (inStream);
   numElements = 0;

   // Read first value
   inStream >> value;

   // Loop until end of file or array is full
   while ((!inStream.eof()) && (numElements < capacity)) 
   {
      // Put value into array
      theArray[numElements] = value;
      numElements++;

      // Read next value
      inStream >> value;
   }  // end for
   if (numElements == capacity)
     cout << "\nWarning: array is full; possibly ignoring input values\n";
   inStream.close();
}  // end ReadArray


// Function: PrintArray
// This function prints out the elements of an array NUM_IN_LINE on a line
// Assumes the array has been initialized
void PrintArray (const double theArray[], // RECEIVED: array to be printed
                 int numElements)         // RECEIVED: number of elements used
{
   const int NUM_IN_LINE = 5;

   // Formatting
   cout.precision(2);
   cout.setf(ios::fixed);
   cout.setf(ios::showpoint);

   for (int i = 0; i < numElements; i++)
   {
      if (i % NUM_IN_LINE == 0)
         cout << endl;
      cout << setw(7) << theArray[i];
   }  // end for
   cout << endl;
}  // end PrintArray


// Function: WriteArray
// This function writes out the elements of an array to a file, one on a line
// Assumes the array has been initialized
void WriteArray (const double theArray[], // RECEIVED: array to be written
                 int numElements)         // RECEIVED: number of elements used
{
   ofstream outStream;  // output file stream

   InteractiveOpen(outStream);
   for (int i = 0; i < numElements; i++)
      outStream << theArray[i] << endl;
   outStream.close();
}  // end WriteArray

// Function:Swap
// Exchanges two values
void Swap (double & first,    // RECEIVED & PASSED BACK: first number
           double & second)   // RECEIVED & PASSED BACK: second number
{
   double temporary = first;
   first = second;
   second = temporary;
}  // end Swap
