
// This program reads an input file and outputs the words from
// that file, along with their line numbers.  An input and output
// file can be specified on the command line.  If only one file
// is specifed, output is written to standard output.  If no files
// are specified, the input is taken from standard input and the
// output is sent to standard output.

#include <fstream>
#include <iostream>
#include <string>
#include <cctype>
using namespace std;


/**
 *  Process one word, from the line with line number line num.
 */
void processWord(string word, int linenum, ostream &out) {
   out << word << " ";
}


/**
 *  Process one line from the file.  The linenum parameter gives
 *  the line number of the line in the input file.
 */
void processLine(string line, int linenum, ostream &out) {
   out << "Line " << linenum << ": ";
   int i = 0;
   string word = "";
   while (true) {
      if (i == line.length())
         break;
      if ((line[i] == '\'' || line[i] == '-')
            && i+1 < line.length() && isalpha(line[i+1]) && word != "") {
         word += line[i];
         word += line[i+1];
         i += 2;
      }
      else if (isalpha(line[i])) {
         word += tolower(line[i]);
         i++;
      }
      else {
         if (word != "") {
            processWord(word,linenum,out);
            word = "";
         }
         i++;
      }
   }
   if (word != "")
      processWord(word,linenum,out);
   out << endl;
}


/**
 *  Process input from the input stream, in, until the end of the
 *  stream is reached (or until an output error occurs).  Output
 *  is written to the output stream, out.
 */
void processFile(istream& in, ostream& out) {
   int linenum = 0;
   while (true) {
      string line;
      getline(in,line);
      if (!in)
         break;
      linenum++;
      processLine(line,linenum,out);
      if (!out) {
         cerr << "Error while writing output file.\n";
         exit(1);
      }
   }
}


int main(int argc, char **argv) {
   if (argc == 1) {  // no command line parameters.
      processFile(cin,cout);
   }
   else if (argc == 2) {  // one command line parameters.
      ifstream input(argv[1]);
      if (!input) {
         cerr << "Can't open input file, \"" << argv[1] << "\".\n";
         return 1;
      }
      else
         processFile(input,cout);
   }
   else if (argc == 3) {  // two command line parameters.
      ifstream input(argv[1]);
      if (!input) {
         cerr << "Can't open input file, \"" << argv[1] << "\".\n";
         return 1;
      }
      else {
         ofstream output(argv[2]);
         if (!output) {
            cerr << "Can't open output file, \"" << argv[2] << "\".\n";
            return 1;
         }
         processFile(input,output);
      }
   }
   else {
      cerr << "Usage:  " << argv[0] << " [inputfile [outputfile]].\n";
      return 1;
   }
   return 0;
}


