Возможные причины сбоя функции Tellg()?
-
22-09-2019 - |
Вопрос
ifstream::tellg()
возвращает -13 для определенного файла.
По сути, я написал утилиту, которая анализирует некоторый исходный код;Я открываю все файлы в алфавитном порядке, начинаю с «Apple.cpp», и все работает отлично..Но когда он доходит до «Conversion.cpp», всегда в одном и том же файле, после успешного чтения одной строки, метод Tellg() возвращает -13.
Код, о котором идет речь:
for (int i = 0; i < files.size(); ++i) { /* For each .cpp and .h file */
TextIFile f(files[i]);
while (!f.AtEof()) // When it gets to conversion.cpp (not on the others)
// first is always successful, second always fails
lines.push_back(f.ReadLine());
Код для AtEof
является:
bool AtEof() {
if (mFile.tellg() < 0)
FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
if (mFile.tellg() >= GetSize())
return true;
return false;
}
После успешного чтения первой строки Conversion.cpp он всегда аварийно завершает работу с DEBUG - tellg(): -13
.
Это все TextIFile
class (написал я, возможно там ошибка):
class TextIFile
{
public:
TextIFile(const string& path) : mPath(path), mSize(0) {
mFile.open(path.c_str(), std::ios::in);
if (!mFile.is_open())
FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno));
}
string GetPath() const { return mPath; }
size_t GetSize() { if (mSize) return mSize; const size_t current_position = mFile.tellg(); mFile.seekg(0, std::ios::end); mSize = mFile.tellg(); mFile.seekg(current_position); return mSize; }
bool AtEof() {
if (mFile.tellg() < 0)
FATAL(format("DEBUG - tellg(): %d") % mFile.tellg());
if (mFile.tellg() >= GetSize())
return true;
return false;
}
string ReadLine() {
string ret;
getline(mFile, ret);
CheckErrors();
return ret;
}
string ReadWhole() {
string ret((std::istreambuf_iterator<char>(mFile)), std::istreambuf_iterator<char>());
CheckErrors();
return ret;
}
private:
void CheckErrors() {
if (!mFile.good())
FATAL(format("An error has occured while performing an I/O operation on %s") % mPath);
}
const string mPath;
ifstream mFile;
size_t mSize;
};
Платформа — Visual Studio, 32-разрядная версия, Windows.
Редактировать: Работает на Linux.
Редактировать: Я нашел причину:окончания строк.И Conversion, и Guid, и другие имели вместо .Вместо этого я сохранил их с помощью , и это сработало.Тем не менее, этого не должно произойти, не так ли?
Решение
Трудно угадать, не зная точно, что внутри. Conversion.cpp
.Однако, используя <
с позициями потока не определяется стандартом.Возможно, вам захочется рассмотреть возможность явного приведения к правильному целочисленному типу перед его форматированием;Я не знаю, какое форматирование FATAL
и format()
ожидать выполнения или как %
оператор перегружен.Позиции в потоке не обязательно должны сопоставляться с целыми числами, особенно если файл не открыт в двоичном режиме.
Возможно, вы захотите рассмотреть альтернативную реализацию для AtEof()
.Скажите что-нибудь вроде:
bool AtEof()
{
return mFile.peek() == ifstream::traits_type::eof();
}