Почему std :: ifstream не обновляется, если он определен глобально

0

Я пытаюсь написать простую программу хвоста в C++. Я пробовал пример из этого решения, и он работает как шарм.

Затем я попытался сделать ifstream глобальным. Теперь код больше не работает, и ничего не отображается, если я редактирую файл.

Почему это поведение? Я прочитал руководство ifstream::open и я не вижу никакой ошибки, но код не работает:

Открывает файл, идентифицированный именем файла аргумента, связав его с объектом потока, так что операции ввода/вывода выполняются над его содержимым. Режим аргумента указывает режим открытия.

Вот нерабочий код:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int find_last_linefeed(ifstream &infile) {
  infile.seekg(0,ios::end);
  int filesize = infile.tellg();
  for(int n=1;n<filesize;n++) {
    infile.seekg(filesize-n-1,ios::beg);
    char c;
    infile.get(c);
    if(c == 0x0A) return infile.tellg();
  }
}

ifstream infile;

int main() {
  int last_position=-1;
  for(;;) {
    infile.open("/Users/alberto/tmp/test");

    int position = find_last_linefeed(infile);
    if(position > last_position) {
      infile.seekg(position,ios::beg);
      string in;
      infile >> in;
      cout << in << endl;
    }
    last_position=position;
    sleep(1);
  }
}

Вот рабочий код:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int find_last_linefeed(ifstream &infile) {
  infile.seekg(0,ios::end);
  int filesize = infile.tellg();
  for(int n=1;n<filesize;n++) {
    infile.seekg(filesize-n-1,ios::beg);
    char c;
    infile.get(c);
    if(c == 0x0A) return infile.tellg();
  }
}


int main() {
  int last_position=-1;
  for(;;) {

    ifstream infile;

    infile.open("/Users/alberto/tmp/test");

    int position = find_last_linefeed(infile);
    if(position > last_position) {
      infile.seekg(position,ios::beg);
      string in;
      infile >> in;
      cout << in << endl;
    }
    last_position=position;
    sleep(1);
  }
}
  • 0
    вы используете глобальные переменные?
  • 0
    Я не вижу ученика.
Показать ещё 5 комментариев
Теги:
ifstream

1 ответ

2
Лучший ответ

Поскольку вы open внутри цикла, поток войдет в состояние ошибки на второй итерации и продолжит сбой после этого.

Переехать

infile.open("/Users/alberto/tmp/test");

вне цикла, или определите infile как это, и вообще не используйте open:

ifstream infile("/Users/alberto/tmp/test");

Лучшая альтернатива - вообще не использовать глобальную переменную, так как здесь нет оснований.

Кроме того, find_last_linefeed не возвращает ничего, если файл не содержит строку, которая не определена.

-

Что касается ifstream::open, из стандарта (27.9.1.9):

Вызывает rdbuf() → open (s, mode | ios_base :: in). Если эта функция не возвращает нулевой указатель, вызовите clear(), в противном случае вызовы setstate (failbit)

и basic_filebuf::open (27.9.1.4):

Если is_open()! = False, возвращает нулевой указатель

  • 0
    Согласно документации по std::basic_filebuf::open , повторное открытие не должно вести себя так, как вы описали, но должно возвращать null и продолжать работать.
  • 0
    что вы имеете в виду под "состоянием ошибки"?
Показать ещё 10 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню