
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <cstdlib> // For EXIT_FAILURE and atoi

class CSVfile {
private:
  std::ifstream csvfile;
  std::string FileName;
  int NumRows;
  int NumCols;
public:
  CSVfile(void);
  ~CSVfile(void);
  int CountRows(void) {return(NumRows);};
  int CountCols(void) {return(NumCols);};
  std::string getcell(void);
  std::string name(void)   {return(FileName);};
  bool eof(void)      {return(csvfile.eof());};
};

CSVfile::CSVfile(void)
{
  std::cout << "Enter the file name : ";
  std::cin >> FileName; // "Library.csv";
  csvfile.open(FileName.c_str());
  if (csvfile.fail())
  {
    std::cerr << "Error - can't open " << FileName << std::endl;
    exit(EXIT_FAILURE);
  }

  // First count the number of rows and cols
  NumRows=0;
  NumCols=0;

  char c;
  csvfile.get(c);
  // Read the first line
  while((c!='\n') && (!eof()) )
  {
    if (c==',')
      NumCols++;
    csvfile.get(c);
  }
  NumCols++;
  NumRows++;
  // Now read the rest
  csvfile.get(c);
  while( !eof() )
  {
    if (c=='\n')
      NumRows++;
    csvfile.get(c);
  }
  csvfile.clear(); // Clear the eof flag
  csvfile.seekg(std::ios::beg); // rewind to beginning.
}

CSVfile::~CSVfile(void)
{
  csvfile.close();
}

std::string CSVfile::getcell(void)
{
  char c;
  std::string cell="";
  csvfile.get(c);
  int i=0;
  while( (c!='\n') && (c!=',') && !eof()  )
  {
    cell+=c;
    i++;
    csvfile.get(c);
  }
  return(cell);
}


int main(void)
{
  CSVfile InFile;

  std::cout << "Opened " << InFile.name()
	    <<  ". It has " << InFile.CountRows() << " rows, and "
	    <<  InFile.CountCols() << " cols." << std::endl;

  std::string *Author, *Title, *CallNumber;

  Author = new std::string [InFile.CountRows()];
  Title = new std::string [InFile.CountRows()];
  CallNumber = new std::string [InFile.CountRows()];

  for (int i=0; i<InFile.CountRows(); i++)
  {
    Title[i] = InFile.getcell();
    Author[i] = InFile.getcell();
    CallNumber[i] = InFile.getcell();
    std::cout << std::setw(18) << Author[i] << ": "
	      << std::setw(38) << Title[i]
	      << std::setw(6) << CallNumber[i] << std::endl;
  }

  delete [] Author;
  delete [] Title;
  delete [] CallNumber;

  return(0);
}
