// Purpose: copy file // // Command syntax: // $ ./a.out [ size (>= 0) | 'd' (default 20) [ code (>= 0) | 'd' (default 5) [ input-file [ output-file ] ] ] ] // all parameters are optional. Defaults: size=>20, code=>5, input=>cin, output=>cout // // Examples: // $ ./a.out 34 // $ ./a.out 34 0 // $ ./a.out 34 0 in // $ ./a.out 34 0 in out #include #include using namespace std; // direct access to std #include // strcmp #include "convert.h" // correct stoi int main( int argc, char * argv[] ) { enum { DefaultSize = 20, DefaultCode = 5 }; // global defaults // MUST BE INT (NOT UNSIGNED) TO CORRECTLY TEST FOR NEGATIVE VALUES intmax_t size = DefaultSize, code = DefaultCode; // default value istream * infile = &cin; // default value ostream * outfile = &cout; // default value cin.exceptions( ios_base::badbit | ios_base::failbit | ios_base::eofbit ); cout.exceptions( ios_base::badbit | ios_base::failbit ); struct cmd_error {}; try { switch ( argc ) { case 4: case 5: try { // open input file first as output creates file infile = new ifstream( argv[3] ); infile->exceptions( ios_base::badbit | ios_base::failbit | ios_base::eofbit ); } catch( ios_base::failure ) { // open failed ? cerr << "Error! Could not open input file \"" << argv[3] << "\"" << endl; throw cmd_error{}; } // try if ( argc == 5 ) { try { outfile = new ofstream( argv[4] ); outfile->exceptions( ios_base::badbit | ios_base::failbit ); } catch( ios_base::failure ) { // open failed ? cerr << "Error! Could not open output file \"" << argv[4] << "\"" << endl; throw cmd_error{}; } // try } // if // FALL THROUGH case 3: if ( strcmp( argv[2], "d" ) != 0 ) { // default ? code = convert( argv[2] ); if ( code < 0 ) throw cmd_error{}; // invalid ? } // if // FALL THROUGH case 2: if ( strcmp( argv[1], "d" ) != 0 ) { // default ? size = convert( argv[1] ); if ( size < 0 ) throw cmd_error{}; // invalid ? } // if // FALL THROUGH case 1: // defaults break; default: // wrong number of options throw cmd_error{}; } // switch } catch( ... ) { // catch any cerr << "Usage: " << argv[0] << " [ size (>= 0) | 'd' (default " << DefaultSize << ") [ code (>= 0) | 'd' (default " << DefaultCode << ") [ input-file [ output-file ] ] ] ]" << endl; exit( EXIT_FAILURE ); // TERMINATE } // try //cout << "size " << size << " code " << code << endl; *infile >> noskipws; // turn off white space skipping during input char ch; try { // eof raises exception for ( ;; ) { // copy input file to output file *infile >> ch; // read a character *outfile << ch; // write a character } // for } catch( ios_base::failure ) { // eof } // try if ( infile != &cin ) delete infile; // close file, do not delete cin! if ( outfile != &cout ) delete outfile; // close file, do not delete cout! } // main