M
Marcus Kwok
I am working on a program that reads and processes large text files (on
the order of 32 MB, so not too huge), so I wanted to add a progress
indicator so I can estimate when it will finish. I just need an
estimate, so the exact byte count isn't essential.
// reduced code
// assume necessary #include's and using declarations for std
// components
ifstream file(filename.c_str());
// read 2 header lines
for (int i = 0; i != 2; ++i) {
string header;
getline(file, header);
}
ifstream:os_type start_of_data = file.tellg();
file.seekg(0, ios::end);
ifstream:os_type end_of_data = file.tellg();
file.seekg(start_of_data);
for (string line; getline(file, line); ) {
do_something_with(line);
int percent_done =
static_cast<unsigned long>(file.tellg()) * 100 / end_of_data;
cout << percent_done << "%\n";
}
This outline seems to work well. My question is: is the cast from the
return type of ifstream::tellg() to unsigned long well-defined? The
reason I am casting to an unsigned type in the first place is that
without the cast, eventually negative percents were being displayed.
Also, are there any other issues with my usage of tellg()? I remember
reading somewhere that the result of tellg() isn't guaranteed to be able
to represent any valid filesize, but I don't know if there is any way
around this issue using only standard components.
the order of 32 MB, so not too huge), so I wanted to add a progress
indicator so I can estimate when it will finish. I just need an
estimate, so the exact byte count isn't essential.
// reduced code
// assume necessary #include's and using declarations for std
// components
ifstream file(filename.c_str());
// read 2 header lines
for (int i = 0; i != 2; ++i) {
string header;
getline(file, header);
}
ifstream:os_type start_of_data = file.tellg();
file.seekg(0, ios::end);
ifstream:os_type end_of_data = file.tellg();
file.seekg(start_of_data);
for (string line; getline(file, line); ) {
do_something_with(line);
int percent_done =
static_cast<unsigned long>(file.tellg()) * 100 / end_of_data;
cout << percent_done << "%\n";
}
This outline seems to work well. My question is: is the cast from the
return type of ifstream::tellg() to unsigned long well-defined? The
reason I am casting to an unsigned type in the first place is that
without the cast, eventually negative percents were being displayed.
Also, are there any other issues with my usage of tellg()? I remember
reading somewhere that the result of tellg() isn't guaranteed to be able
to represent any valid filesize, but I don't know if there is any way
around this issue using only standard components.