Возможные причины сбоя Tellg ()? - PullRequest
0 голосов
/ 23 января 2010

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 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, и у других есть \ n вместо \ r \ n. Я сохранил их с помощью \ r \ n, и это сработало. Тем не менее, это не должно произойти, не так ли?

1 Ответ

1 голос
/ 23 января 2010

Трудно угадать, не зная точно, что в Conversion.cpp. Однако использование < с позициями потока не определено стандартом. Возможно, вы захотите рассмотреть явное приведение к правильному целочисленному типу перед его форматированием; Я не знаю, какие форматирования FATAL и format() ожидают выполнить или как перегружен оператор % Позиции потоков не должны отображаться предсказуемым образом в целые числа, особенно если файл не открывается в двоичном режиме.

Возможно, вы захотите рассмотреть альтернативную реализацию для AtEof(). Скажите что-то вроде:

bool AtEof()
{
    return mFile.peek() == ifstream::traits_type::eof();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...