Смешивание freopen и ncurses
У меня проблемы с микшированием freopen
из stdin
вместе с библиотекой ncurses.
Что я делаю, это снова открываю стандартный файл в файл, анализирую его с помощью flex+bison, затем я должен вернуть его обратно и запустить ncurses.
Код для обмена является следующим:
void switchStdin(const char *newStream) {
fflush(stdin);
fgetpos(stdin, &pos);
fd = dup(fileno(stdin));
freopen(newStream, "r", stdin);
}
void revertStdin() {
fflush(stdin);
dup2(fd, fileno(stdin));
close(fd);
clearerr(stdin);
fsetpos(stdin, &pos);
}
В моем лексере это то, что я делаю:
void parse() {
Utils::switchStdin("./filename.ext");
yyparse();
Utils::revertStdin();
}
и в основном файле я просто делаю что-то вроде
parse();
initscr();
keypad(stdscr, TRUE);
noecho();
cbreak();
...
Теперь, если я не буду комментировать revertStdin
он просто останавливается при запуске, если вместо этого я комментирую, синтаксический анализ работает, но графический интерфейс ncurses не отвечает и время от времени мигает.
Поскольку обе части работают независимо друг от друга, я предполагаю, что есть некоторая оговорка в их последовательном смешении, которое я пропускаю. У кого-нибудь есть ключ?
1 ответ
Там больше, чем одна проблема, но важная revertStdin
не удается открыть поток:
switchStdin
излишне называет непереносимымfflush(stdin)
,- он сохраняет дескриптор файла для
stdin
вfd
и положение файла вpos
, - положение файла не требуется (поскольку терминалы этого не делают)
revertStdin
излишне называет непереносимымfflush(stdin)
,- он пытается переписать файловый дескриптор
stdin
используя сохраненныйfd
, Это не сработает. - в некоторых системах вы не можете присвоить новое значение
stdin
; бывает, что библиотека GNU C позволяет это. Если вы используете Linux, вы можете решить проблему, используяfdopen
например,
stdin = fdopen (fd, "r");
- если нет (более переносимо) вы бы использовали
newterm
скорее, чемinitscr
, В отличие отinitscr
,newterm
позволяет указать потоки для ввода и вывода. В этом случае вы все равно используетеfdopen
, но не пытаться назначитьstdin
, Используйте свою собственную переменную и передайте ееnewterm
,