Nano Hash - криптовалюты, майнинг, программирование

Как проверить, пуст ли stdin в C

Я (пере) изучаю C-программирование, поэтому следующий вопрос предназначен для понимания. Используя scanf (), я узнал (или выяснил сам, на самом деле это не займет много времени, чтобы дойти до этого момента), что очистка stdin - это хорошо. Далее я узнал (с вашей помощью), что fflush (stdin) не является стандартным делом и, например, не работает с gcc. Я перешел к использованию приведенного ниже фрагмента кода для очистки стандартного ввода-вывода. Он был предоставлен здесь (спасибо). Он отлично работает, если stdin не пуст. Тем не менее, если stdin пуст, он не работает. Функция fgetc () в моей функции очистки просто ждет и блокирует программу. Фактически, все другие известные мне функции чтения stdin (scanf (), fgetc (), gets (), fgets (), getchar ()) демонстрируют такое же поведение. Таким образом, моя функция очистки на самом деле является условной очисткой: она очищается только в том случае, если буфер не пуст. Если он пуст, промывка блокирует программу и ожидает ввода на стандартный ввод. Это не то, что я хочу. Итак, мне нужен способ проверить, пуст ли stdin. Если это так, я продолжаю. Если это не так, я запускаю свою функцию промывки.

Итак, я ищу стандартный способ C проверить, пуст ли stdin.

Большое спасибо за любую помощь!

void flush_line(FILE *);


/* function to flush stdin in a C standard way since*/
/* fflush(stdin) has undefined behaviour. */
/* s. http://stackoverflow.com/questions/20081062/fflushstdin-does-not-work-compiled-with-gcc-in-cygwin-but-does-compiled-with-v */
void flush_line(FILE *fin)
{
    int ch;
    do
    {
        ch = fgetc(fin);

    } while (ch != '\n' && ch != EOF);

}
30.11.2013

  • К сожалению, это может не сработать, поскольку fgetc заблокируется, если нет символов для чтения. 30.11.2013
  • Что именно вы имеете в виду, говоря об очистке входного потока? 30.11.2013
  • Под промывкой я подразумеваю опорожнение входного потока, чтобы убедиться, что там нет ничего, чего не должно быть, например. перед тем, как запрашивать ввод пользователя и читать его со стандартного ввода. 30.11.2013
  • @CharlesBailey, наверное, consuming все оставшиеся в нем данные ... 30.11.2013
  • О, и если fin - это файл (а не stdin), тогда вы не можете знать, продолжает ли реализация буферизоваться непрерывно, поэтому буфер, возможно, никогда не опустеет. 30.11.2013
  • И если вы хотите читать только до тех пор, пока не появится новая строка, используйте fgets с умеренно большим буфером. 30.11.2013
  • c-faq.com/stdio/gets_flush2.html 30.11.2013
  • И как отличить ввод, который является законным, от ввода, которого не должно быть? 30.11.2013
  • @Zaffy Я не уверен, что это правильно, а что, если ch == 'c' тогда 'c' != '\n' && 'c' != EOF. Я считаю, что это логическая тавтология, если использовать || 01.12.2013
  • Вы думали о выборе? Конечно, вы должны установить, что stdin неблокирован, это совсем другая история. gnu.org/software/libc/manual/html_node/ Waiting-for-I_002fO.html 01.12.2013
  • Так нет конкретного решения для этого? :/ Грустный. 20.09.2017

Ответы:


1

Вы можете использовать select или poll, чтобы проверить, доступен ли дескриптор файла для чтения. Но не в ANSI C.

01.12.2013

2

Я решил это злокачественным способом, но работает нормально. Если работает только тогда, когда stdin грязный (не пустой), тогда просто отправляйте \n на stdin всегда, прежде чем очищать его. Да, я знаю, это кажется очень уродливым решением, но это единственный разумный способ, который я считаю переносимым, поскольку select или poll не работают с Windows).

Вот:

void flush_stdin() {
    char c;
    ungetc('\n', stdin); // ensure that stdin is always dirty
    while(((c = getchar()) != '\n') && (c != EOF));
}
20.09.2017
  • Теперь цикл while немедленно останавливается, потому что вы выбрали '\ n', который он ищет. 07.03.2019

  • 3

    Не думайте о stdin как о месте, где данные доступны или недоступны. Он называется потоком по какой-то причине: вас всегда интересуют следующие данные из него, когда они могут быть доступны.

    Конкретно, вы решаете «промыть» (возможно, «осушить» было бы лучше) поток по причине. Возможно, вы запросили у пользователя целое число, а вместо этого они ввели буквы. Тогда вы знаете, что поток не «пустой», потому что в нем есть буквы! Так что чтение до следующей новой строки - разумная идея.

    Или, возможно (для совместимости с какой-либо другой утилитой?) У вас есть протокол, в котором определенная строка ввода не имеет значения. Затем вы можете «осушить» эту линию; не имеет значения, набрал ли пользователь что-нибудь еще, потому что вам нужно дождаться, пока он это наберет, прежде чем вы все равно сможете принять от него какие-либо дополнительные данные.

    20.09.2017
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..