I am encountering a situation that I don't quite know where to look after the cause of the issue for, as the problem seems to only occur when piping the program output from the terminal into a file and I have no idea what that might have to do with my code itself. Furthermore this only happens for larger files and not for small ones;
I wrote a file reader class with an output iterator:
#include <fstream>
#include <iostream>
#include <limits>
class Filereader
{
private:
std::fstream file;
class output_iterator
{
public:
output_iterator(std::fstream& file, int line_number)
: file(file), line_number(line_number)
{
if (line_number == 0 || line_number == -1) {
} else {
go_to_line(line_number);
}
}
const std::string& operator*() const { return line; }
output_iterator& operator++()
{
if (file.good()) {
getline(file, line);
line_number++;
} else {
line_number = -1;
}
return *this;
}
friend bool operator!=(const output_iterator& lhs,
const output_iterator& rhs)
{
return !(lhs == rhs);
}
friend bool operator==(const output_iterator& lhs,
const output_iterator& rhs)
{
if (&lhs.file != &rhs.file)
throw(std::invalid_argument("file operands do not match"));
return lhs.line_number == rhs.line_number;
}
private:
void go_to_line(size_t num)
{
file.seekg(0, std::ios::beg);
for (size_t i = 0; i < num - 1; ++i) {
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
private:
std::fstream& file;
std::string line;
int line_number;
};
public:
Filereader(const std::string& filename)
{
file.exceptions(std::fstream::failbit | std::fstream::badbit);
try {
file.open(filename, std::ios::in);
} catch (const std::fstream::failure& e) {
std::cerr << "exception opening file '" + filename + "'"
<< "\n";
}
}
output_iterator begin() { return output_iterator(file, 0); }
output_iterator end() { return output_iterator(file, -1); }
};
and my test program is this:
int main(int argc, char** argv){
Filereader fr(argv[1]);
for (auto i = fr.begin(); i != fr.end(); ++i){
std::cout << *i << "\n";
}
}
Now, piping the output actually goes through successfully, but after that the following error is thrown:
terminate called after throwing an instance of 'std::ios_base::failure[abi:cxx11]'
what(): basic_ios::clear: iostream error
And as mentioned this only happens for larger files.
When not piping the output, no error is being thrown... I am probably missing something really obvious here, but I don't know where to look for the cause of this.