Как проверить, есть ли в моей программе данные, переданные в нее

Я пишу программу, которая должна читать ввод через стандартный ввод, поэтому у меня есть следующая конструкция.

FILE *fp=stdin;

Но это просто зависает, если пользователь ничего не передал в программу, как я могу проверить, действительно ли пользователь передает данные в мою программу, например

gunzip -c file.gz |./a.out #should work
./a.out  #should exit program with nice msg.

Благодарность


person monkeyking    schedule 02.04.2010    source источник
comment
Кстати, программа не зависает; он просто ждет ввода. Если вы отправляете EOF (Ctrl-D на большинстве платформ), это интерпретируется так, как будто ввод закончился раньше.   -  person greyfade    schedule 02.04.2010


Ответы (6)


Поскольку вы используете файловые указатели, для этого вам понадобятся как isatty(), так и fileno():

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    FILE* fp = stdin;

    if(isatty(fileno(fp)))
    {
        fprintf(stderr, "A nice msg.\n");
        exit(1);
    }

    /* carry on... */
    return 0;
}

На самом деле это долгий путь. Короткий способ - не использовать файловые указатели:

#include <unistd.h>

int main(int argc, char* argv[])
{
    if(isatty(STDIN_FILENO))
    {
        fprintf(stderr, "A nice msg.\n");
        exit(1);
    }

    /* carry on... */
    return 0;
}

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

person Mike DeSimone    schedule 02.04.2010

Попробуйте "man isatty", я думаю, эта функция скажет вам, разговариваете ли вы с пользователем или нет.

person Jeremy Friesner    schedule 02.04.2010

Передача стандартного ввода в select() или poll() должна сообщить вам, ожидает ли ввод. Во многих операционных системах вы также можете определить, является ли стандартный ввод tty или каналом.

РЕДАКТИРОВАТЬ: я вижу, что мне придется подчеркнуть также часть теста tty. Fifo — это не tty, но может не быть ввода, готового на неопределенное время.

person Ben Voigt    schedule 02.04.2010
comment
Я думаю, что ОП просто хотел охватить случай запуска в командной строке и удивления, почему он зависает. Вероятно, пытается исправить ошибку PEBKAC. Сидеть там, ожидая FIFO или другой трубы, было бы нормально. - person Mike DeSimone; 02.04.2010

Используйте isatty, чтобы определить, что стандартный ввод поступает с терминала, а не с перенаправления.

person Marcelo Cantos    schedule 02.04.2010

См. функцию "isatty" - если STDIN является терминалом, чтение из него можно пропустить. Если это не терминал, вы получаете данные по конвейеру или перенаправляете, и вы можете читать до EOF.

person nobody    schedule 02.04.2010

Дополнительная опция, которую вы получаете с помощью select(), устанавливает тайм-аут для чтения из стандартного ввода (относительно первого чтения из стандартного ввода или последовательных чтений из стандартного ввода).

Пример кода с использованием select на стандартном вводе см. в следующем разделе:

Как проверить, открыт ли стандартный ввод без блокировки?< /а>

person kroener    schedule 02.04.2010