Code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void getNewHeader( fstream & );
int getNumLinesHeader( fstream & );
void getNewColumnTitles( fstream &, const int & );
bool isNotInt( const char & );
void transferData( fstream &, fstream & );
void displayHeader( fstream &, int & );
void displayData( fstream &, const int & );
void arrangeData( fstream &, const int &, char [], int & );
int menuChoice();
int getNumColumns( fstream & );
void eraseColumn( fstream &, fstream &, int & );
void switchColumns( fstream &, fstream & );
void quit();
void getPastHeader( fstream & );
void copyFile( fstream &, fstream &, char [] );
int main() {
fstream source;
char sourcename[81];
do {
cout << "Enter data source file: ";
cin >> sourcename;
source.open( sourcename, ios::in );
if( !source )
cout << "Invalid file name: File does not exist." << endl;
} while( !source );
fstream target; // stream to read from target file
bool done = false;
char targetname[81];
while( !done ) {
cout << "Enter data target file: ";
cin >> targetname;
if( sourcename == targetname ) {
cout << "Invalid file name: File already exists or " <<
"source file entered as target file." << endl;
}
else {
target.open( targetname, ios::in | ios::out | ios::nocreate );
if( target.is_open() ) {
cout << "File exists, are you sure you want " <<
"to overwrite the file (y/n)? ";
char choice;
cin >> choice;
if( choice == 'n' ) {
cout << "File will not be overwritten," <<
"please enter a new file name." <<
endl;
target.close();
}
else if( choice == 'y' ) {
cout << "File will be overwritten." <<
endl;
done = true;
}
}
else
done = true;
}
}
target.open( targetname, ios::in | ios::out | ios::noreplace );
// display the header and set the number of lines of the header
int header_lines = 0;
displayHeader( source, header_lines );
// display the data
displayData( source, header_lines );
getNewHeader( target );
int num_columns = getNumColumns( source );
getNewColumnTitles( target, num_columns );
transferData( source, target );
arrangeData( source, header_lines, targetname, num_columns );
source.close();
target.close();
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void displayHeader( fstream &source, int &header_lines ) {
header_lines = getNumLinesHeader( source );
cout << endl;
// display the header
if( header_lines > 0 ) {
cout << "The original header:" << endl;
for( int i = 0; i < header_lines; i++ ) {
string curr_line = "";
getline( source, curr_line );
cout << curr_line << endl;
}
}
else
cout << "Original header not displayed." << endl;
cout << endl;
}
void displayData( fstream &source, const int &header_lines ) {
cout << "How many lines of data would you like to view? ";
int data_lines;
cin >> data_lines;
cout << endl;
if( data_lines > 0 ) {
string curr_line;
getline( source, curr_line );
cout << "The original data:" << endl;
for( int i = header_lines; i < header_lines + data_lines; i++ ) {
getline( source, curr_line );
cout << curr_line << endl;
}
}
else
cout << "Original data not displayed." << endl;
cout << endl;
}
int getNumLinesHeader( fstream &source ) {
source.seekg( 0 );
int lines = 0;
bool done = false;
while( !done ) {
char c;
source >> c;
if( isNotInt( c ) ) {
string temp_line;
getline( source, temp_line );
lines++;
}
else {
source.putback( c );
done = true;
}
}
source.seekg( 0 );
return lines;
}
bool isNotInt( const char &c ) {
int i = static_cast<int>( c );
if( c != '-' && c != '.' && ( i < 48 || i > 57 ) )
return true;
return false;
}
void getNewHeader( fstream &target ) {
char choice = '!';
while( choice != 'y' && choice != 'n' ) {
cout << "Would you like to include a header in the file (y/n)? ";
cin >> choice;
if( choice != 'y' && choice != 'n' )
cout << "Please enter either y or n." << endl;
}
if( choice == 'y' ) {
cout << "When you are done entering text, simply enter a blank" <<
" line." << endl;
string header_line = "!";
getline( cin, header_line );
bool done = false;
while( !done ) {
cout << "> ";
getline( cin, header_line );
if( header_line != "%" )
target << header_line << endl;
else {
target << endl;
done = true;
}
}
}
}
void getNewColumnTitles( fstream &target, const int &num_columns ) {
cout << endl;
cout << "There are " << num_columns << " columns of data." << endl;
cout << "Please enter new column titles..." << endl;
string new_header;
for( int i = 1; i < num_columns; i++ ) {
cout << "Column #" << i << ": ";
cin >> new_header;
target << new_header << " | ";
}
cout << "Column #" << num_columns << ": ";
cin >> new_header;
target << new_header << endl;
}
int getNumColumns( fstream &source ) {
getPastHeader( source );
string line;
// capture a line of data
getline( source, line );
int i = 0, columns = 1;
bool last_space = false;
while( i < static_cast<int>( line.length() ) ) {
if( line[i] == ' ' ) {
if( last_space )
line.erase( i, 1 );
else {
i++;
last_space = true;
}
}
else {
last_space = false;
i++;
}
}
if( line[0] == ' ' )
line.erase( 0, 1 );
if( line[ line.length()-1 ] == ' ' )
line.erase( line.length()-1, 1 );
// count columns
for( i = 0; i < static_cast<int>( line.length() ); i++ )
if( line[i] == ' ' )
columns++;
return columns;
}
void getPastHeader( fstream &source ) {
source.seekg( 0 );
bool done = false;
int curr_line = 0, header_lines = getNumLinesHeader( source );
string line;
while( !done ) {
getline( source, line );
curr_line++;
if( curr_line == header_lines || !source )
done = true;
}
getline( source, line );
}
void transferData( fstream &source, fstream &target ) {
cout << "data transfer";
source.seekg( 0 );
source.seekp( 0 );
target.seekg( 0 );
target.seekp( 0 );
while( !source.eof() ) {
cout << "...";
string line;
getline( source, line );
target << line << endl;
}
cout << endl;
source.seekg( 0 );
source.seekp( 0 );
target.seekg( 0 );
target.seekp( 0 );
}
///////////////////////////////////////////////////////////////////////////
void arrangeData( fstream &target, const int &header_lines,
char targetname[], int &num_columns ) {
int choice = -1;
while( choice != 3 ) {
choice = menuChoice();
if( choice != 3 ) {
fstream temp_file( "temp.dat", ios::in | ios::out );
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
///////// PROBLEM IS IN THE NEXT FUNCTION /////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
copyFile( target, temp_file, targetname );
if( choice == 1 )
eraseColumn( target, temp_file, num_columns );
else if( choice == 2 )
switchColumns( target, temp_file );
}
else
cout << "Exiting program..." << endl << endl;
}
}
void copyFile( fstream &target, fstream &temp_file, char targetname[] ) {
transferData( target, temp_file );
target.close();
target.open( targetname, ios::in | ios::out | ios::trunc );
}
int menuChoice() {
cout << endl << "Menu" << endl;
cout << "----------------------" << endl;
cout << "1. Erase a column." << endl;
cout << "2. Switch two columns." << endl;
cout << "3. Quit." << endl;
cout << "----------------------" << endl;
int choice = 0;
while( choice < 1 || choice > 3 ) {
cout << "> ";
cin >> choice;
if( choice < 1 || choice > 3 )
cout << "Please enter a choice 1-3." << endl;
}
return choice;
}
void eraseColumn( fstream &target, fstream &temp_file, int &num_columns ) {
cout << "***ERASE COLUMN()(***" << endl;
bool input_ok = false;
int erase_column;
while( !input_ok ) {
cout << "Please enter the column you would like to erase," <<
" or 0 to exit: ";
cin >> erase_column;
if( erase_column < 0 || erase_column > num_columns )
cout << "Please enter a valid column." << endl;
else
input_ok = true;
}
if( erase_column != 0 ) {
cout << "***GET PAST TARGET HEADER***"<<endl;
string line;
for( int i = 0; i < getNumLinesHeader( temp_file ); i++ ) {
cout << "(loop)" << endl;
getline( temp_file, line );
target << line << endl;
}
cout << "***enter big while***" << endl;
while( !temp_file.eof() ) {
getline( temp_file, line );
int i = 0, cur_col = 0;
bool last_space = true;
while( i < static_cast<int>( line.length() ) ) {
cout << "***in loop***" << endl;
if( last_space && line[i] != ' ' ) {
last_space = false;
cur_col++;
}
else if( !last_space && line[i] == ' ' )
last_space = true;
if( cur_col != erase_column ) {
char c = line[i];
target << c;
}
i++;
}
target << endl;
}
num_columns--;
}
}