The previous example actually has some subtle bugs that we might want to fix.
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <limits>
bool skiplines(std::istream &is, std::ostream &os) {
std::string line;
while(std::getline(is,line)) {
if(!(os << line)) return false;
if(!is.eof() && !(os << '\n')) return false;
is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
return is.eof();
}
int main(int argc, char *argv[]) {
using namespace std;
const char *iname = (argc>1)?argv[1]:"skiplines.cpp";
string oname = (argc>2)?argv[2]:iname+string(".out",4);
ifstream ifs(iname);
ofstream ofs(oname.c_str());
if(skiplines(ifs,ofs)) {
cout << "Done!" << endl;
} else {
if(!ifs) cerr << "Error processing file " << iname << endl;
if(!ofs) cerr << "Error processing file " << oname << endl;
}
return 0;
}
Ok so this is a bit overboard, but the main point is where I test eof() in the above. A file that has failed for any reason will never reach eof() Thus you check eof after you are done reading to test if the reason you stopped was that your ran out of things to read. eof() has one other subtle use, an that is when getilne reads a line that goes to the end of file, but that does not contain a newline eof is true, but fail is false. It's a perfectly good line, but the previous example bailed out too early. Testing the state of the output stream after every operation is just me being paranoid, but its a good idea to check up how your output is going. in_avail() is the number of bytes in the buffer, not the file, though it could very easily be the total file size. numeric_limits is a good example of how Stroustrup must be getting a kickback from some keyboard manufacturers. Nevertheless it's a good generic way to find things like the largest possible number of whatever type. streamsize is probably size_t, and size_t is probably unsinged long, but this can change and I don't need to know about any of it, because I know about numeric_limits.