// Purpose: copy file // // Command syntax: // $ ./a.out [ size (>= 0) [ code (>= 0) [ 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 #include using namespace std; // direct access to std bool convert( int &val, char *buffer ) { // convert C string to integer std::stringstream ss{ buffer }; // connect stream and buffer string temp; ss >> dec >> val; // convert integer from buffer return ! ss.fail() && // conversion successful ? ! ( ss >> temp ); // characters after conversion all blank ? } // convert enum { sizeDeflt = 20, codeDeflt = 5 }; // global defaults int main( int argc, char *argv[] ) { unsigned int size = sizeDeflt, code = codeDeflt; // default value istream *infile = &cin; // default value, read from stdin ostream *outfile = &cout; // default value, write to stdout bool error = false; string errorMsg; switch ( argc ) { case 5: outfile = new ofstream{ argv[4] }; // open output file if ( outfile->fail() ) { error = true; errorMsg += "could not open output file; "; } // FALL THROUGH case 4: infile = new ifstream{ argv[3] }; // open input file if ( infile->fail() ) { error = true; errorMsg += "could not open input file; "; } // FALL THROUGH case 3: if ( ! convert( (int &)code, argv[2] ) || (int)code < 0 ) { // invalid integer ? error = true; errorMsg += "invalid code; "; } // if // FALL THROUGH case 2: if ( ! convert( (int &)size, argv[1] ) || (int)size < 0 ) { // invalid integer ? error = true; errorMsg += "invalid size; "; } // if // FALL THROUGH case 1: // all defaults break; default: // wrong number of options error = true; errorMsg += "wrong number of arguments; "; } // switch if ( error ) { cerr << "Usage: " << argv[0] << " [ size (>= 0 : " << sizeDeflt << ") [ code (>= 0 : " << codeDeflt << ") [ input-file [ output-file ] ] ] ]" << endl; cerr << errorMsg << endl; return( EXIT_FAILURE ); // TERMINATE } // if *infile >> noskipws; // turn off white space skipping during input char ch; // copy input file to output file while ( *infile >> ch ) { // read a character, *outfile << ch; // write a character } // while if ( infile != &cin ) delete infile; // close file, do not delete cin! if ( outfile != &cout ) delete outfile; // close file, do not delete cout! } // main