// 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 #include // exit 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 ostream *outfile = &cout; // default value infile->exceptions( ios_base::failbit ); // set cin/cout to use exceptions outfile->exceptions( ios_base::failbit ); try { switch ( argc ) { case 5: try { outfile = new ofstream( argv[4] ); // open output file outfile->exceptions( ios_base::failbit ); // set exceptions } catch( ios_base::failure ) { throw ios_base::failure( "could not open output file" ); } // try // FALL THROUGH case 4: try { infile = new ifstream( argv[3] ); // open input file infile->exceptions( ios_base::failbit ); // set exceptions } catch( ios_base::failure ) { throw ios_base::failure( "could not open input file" ); } // try // FALL THROUGH case 3: if ( ! convert( (int &)code, argv[2] ) || (int)code < 0 ) { // invalid integer ? throw ios_base::failure( "invalid code" ); } // if // FALL THROUGH case 2: if ( ! convert( (int &)size, argv[1] ) || (int)size < 0 ) { // invalid integer ? throw ios_base::failure( "invalid size" ); } // if // FALL THROUGH case 1: // all defaults break; default: // wrong number of options throw ios_base::failure( "wrong number of arguments" ); } // switch } catch( ios_base::failure err ) { cerr << err.what() << endl; cerr << "Usage: " << argv[0] << " [ size (>= 0 : " << sizeDeflt << ") [ code (>= 0 : " << codeDeflt << ") [ input-file [ output-file ] ] ] ]" << endl; exit( EXIT_FAILURE ); // TERMINATE } // try *infile >> noskipws; // turn off white space skipping during input try { char ch; for ( ;; ) { // copy input file to output file *infile >> ch; // read a character, raise ios_base::failure at EOF *outfile << ch; // write a character } // for } catch( ios_base::failure ) {} // end of file if ( infile != &cin ) delete infile; // close file, do not delete cin! if ( outfile != &cout ) delete outfile; // close file, do not delete cout! } // main // Local Variables: // // compile-command: "g++ IO.cc" // // End: //