Как определить, будет ли fgets (stdin) блокироваться в Windows? - PullRequest
0 голосов
/ 28 октября 2018

Как узнать, будет ли блокироваться следующий вызов fgets(stdin, ...) или нет?Другими словами, как я могу определить, есть ли в буфере stdin символ новой строки, ожидающий чтения?

В Unix я знаю, что могу использовать select() следующим образом:

    fd_set reads;
    FD_ZERO(&reads);
    FD_SET(fileno(stdin), &reads);
    int s = select(fileno(stdin)+1, &reads, 0, 0, 0);
    if (s) {
        //fgets is ready
    }

Однако select() в Windows работает только с сокетами, а не с 'stdin', поэтому я не могу его использовать.

Я также знаю, что в Unix я могу использовать poll(), ioctl(0, I_NREAD...) и, возможно,много других решений.Ничто из этого не работает в Windows.

Я пробовал kbhit() и WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), )).Проблема состоит в том, что оба они указывают, что ввод доступен, как только будет нажата первая клавиша.Мне нужно знать, доступна ли целая строка, потому что fgets() блокирует всю строку.

Возможно, моя проблема в том, что оболочки Unix имеют тенденцию буферизовать целые строки ввода, а Windows - нет?

Должен ли я просто использовать fgetc() для создания буфера, пока не увижу новую строку?

Я провел исследование, чтобы найти другие ответы, но ни один из них мне не помог.Они либо используют C ++, а мне нужно решение на C.Или они фокусируются на использовании fgets() с сокетами, где мне нужно использовать его с stdin.

Любая помощь очень ценится.Спасибо!

1 Ответ

0 голосов
/ 28 октября 2018

Как узнать, будет ли блокироваться следующий вызов fgets(stdin, ...) или нет?Другими словами, как я могу определить, есть ли в буфере stdin символ новой строки, ожидающий чтения?

В общем, вы не можете сказать.Не в системах POSIX, без каких-либо предположений.И POSIX, и Windows API определяют механизмы для определения доступности ввода, но этого вам недостаточно.Вы хотите определить, доступны ли для чтения конкретные данные (то есть, терминатор строки), и единственный способ, которым C определяет для этого, - это чтение данных.

Поэтому, если вам действительно нужно прочитать строкуза раз, не блокируя ваш основной поток, тогда я предлагаю выполнять ваши чтения асинхронно.Вы можете свернуть свой собственный, с потоком чтения, отдельным от основного, но вы можете обнаружить, что API асинхронного ввода-вывода Microsoft поддерживает ваши потребности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...