2010-04-02 28 views
7

Im viết chương trình đọc đầu vào thông qua stdin hay không, vì vậy tôi có sự đối chiếu sau đây.Làm cách nào để kiểm tra xem chương trình của tôi có dữ liệu được truyền vào trong số

FILE *fp=stdin; 

Nhưng điều này chỉ bị treo nếu người dùng đã không cấp nước tập trung bất cứ điều gì vào chương trình, làm thế nào tôi có thể kiểm tra nếu người dùng đang thực sự đường ống dữ liệu vào chương trình của tôi như

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

nhờ

+0

Đối với hồ sơ, chương trình không phải là treo; nó chỉ đơn giản là chờ đợi cho đầu vào. Nếu bạn gửi một EOF (Ctrl-D trên hầu hết các nền tảng), nó được hiểu là đầu vào đã kết thúc sớm. – greyfade

Trả lời

8

Vì bạn đang sử dụng con trỏ tập tin, bạn sẽ cần cả isatty()fileno() để làm điều này:

#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; 
} 

Trên thực tế, đó là chặng đường dài. Cách ngắn gọn là không sử dụng con trỏ tệp:

#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; 
} 

Một số chương trình Unix chuẩn thực hiện kiểm tra này để sửa đổi hành vi của chúng. Ví dụ: nếu bạn đã thiết lập ls để cung cấp cho bạn màu sắc đẹp, nó sẽ tắt màu nếu bạn đặt đường ống của nó thành chương trình khác.

3

Việc chuyển stdin đến select() hoặc poll() sẽ cho bạn biết nếu đầu vào đang chờ. Dưới nhiều hệ điều hành, bạn cũng có thể biết liệu stdin là một tty hay pipe.

EDIT: Tôi thấy tôi sẽ phải nhấn mạnh phần cũng là của thử nghiệm tty. Một năm mươi không phải là một tty, nhưng có thể không có đầu vào sẵn sàng cho một khoảng thời gian vô hạn định.

+0

Tôi nghĩ rằng OP chỉ muốn bao gồm trường hợp run-on-command-line-and-wonder-why-it- "bị treo". Có thể cố sửa một lỗi PEBKAC. Ngồi đó chờ đợi trên một FIFO hoặc đường ống khác sẽ không sao. –

3

Hãy thử "man isatty", tôi nghĩ rằng chức năng đó sẽ cho bạn biết liệu bạn có đang nói chuyện với người dùng hay không.

2

Sử dụng isatty để phát hiện stdin đó đến từ thiết bị đầu cuối chứ không phải chuyển hướng.

1

Xem hàm "isatty" - nếu STDIN là thiết bị đầu cuối, bạn có thể bỏ qua việc đọc từ đó. Nếu nó không phải là một thiết bị đầu cuối, bạn đang nhận được dữ liệu đường ống hoặc chuyển hướng và bạn có thể đọc cho đến khi EOF.

0

Tùy chọn bổ sung mà bạn nhận được với select() là đặt thời gian chờ để đọc từ stdin (đối với lần đọc đầu tiên từ stdin hoặc lần đọc liên tiếp từ stdin).

Đối với một ví dụ mã sử dụng lựa chọn trên stdin see:

How to check if stdin is still opened without blocking?

Các vấn đề liên quan