2013-04-26 61 views
7

Bu soruya uygun bir cevap alamadım ancak bir linux makinesinde çalışıyorum, standart giriş akışının herhangi bir karakter içerip içermediğini kontrol etmek istedim.Stdin boş olup olmadığını kontrol edin

+1

C++ veya C? Sorunuz her ikisiyle de etiketlenmiştir. –

+3

Sorunuzun iyi tanımlanmış bir anlama sahip olduğundan emin değilim. * Stdin * 'in bir boru olduğunu düşünün (ilk karakteri tükenmekte olan bir komuttan * stdout *' da). Yapabilecekleriniz, [STDIN_FILENO'yu (yani 0) bir dosya tanıtıcısı olarak kullanarak [anket (2)] (http://man7.org/linux/man-pages/man2/poll.2.html) olarak adlandırılabilir. Daha sonra * stdin * 'in okunabilir olup olmadığını kontrol edersiniz (yani [oku (2)] (http://man7.org/linux/man-pages/man2/read.2.html) engellemez). –

cevap

6

select() işlevini denemek ve giriş akışına veri almak için beklemek isteyebilirsiniz.

Açıklama:

select() ve pSELECT(), bir program çoklu dosya tanımlayıcılar izlemek için izin dosya tanımlayıcıları biri veya birkaçı kadar beklemek haline bazı sınıf için "hazır" G/Ç işleminin (örn. giriş mümkün). tanımlayıcı bir dosya, karşılık gelen G/Ç işleminin (ör., Okuma (2)) engellenmeden gerçekleştirilebilmesi durumunda hazır olarak kabul edilir.

Senin durumunda

, dosya tanıtıcı olacak stdin

void yourFunction(){ 
    fd_set fds; 
    struct timeval timeout; 
    int selectRetVal; 

    /* Set time limit you want to WAIT for the fdescriptor to have data, 
     or not(you can set it to ZERO if you want) */ 
    timeout.tv_sec = 0; 
    timeout.tv_usec = 1; 

    /* Create a descriptor set containing our remote socket 
     (the one that connects with the remote troll at the client side). */ 
    FD_ZERO(&fds); 
    FD_SET(stdin, &fds); 

    selectRetVal = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); 

    if (selectRetVal == -1) { 
     /* error occurred in select(), */ 
     printf("select failed()\n"); 
    } else if (selectRetVal == 0) { 
     printf("Timeout occurred!!! No data to fetch().\n"); 
     //do some other stuff 
    } else { 
     /* The descriptor has data, fetch it. */ 
     if (FD_ISSET(stdin, &fds)) { 
      //do whatever you want with the data 
     } 
    } 
} 

yardımcı olur Umut.

+3

Anlık bir yanıt için teşekkürler, ben, giriş akışı veri, sahip olması için beklemek istemiyorum Sadece, veri akışı varsa, veri yoksa, bazı işlemleri yapmak gerekir başka bir işlem. Kod giriş için beklememelidir, – 51k

+0

Hala bunun 51k'ye yardımcı olabileceğini düşünüyorum, bir örnek vereyim. –

4

Cacho Ancak select birden fazla dosya tanımlayıcısı ile uğraşıyoruz yalnızca gereklidir ve stdin bir POSIX dosya tanıtıcı (int) değil doğru yolda vardı; FILE *. O rotaya giderseniz, STDIN_FILENO'u kullanmak istersiniz.

Ya da almak için çok temiz bir yol değil. poll kullanmayı tercih ederim. timeout olarak belirtilerek, anket hemen geri dönecektir. tanımlanmış olayların hiçbiri seçili dosya tanımlayıcı üzerinde meydana gelmiş ise bir olay seçili dosya tanımlayıcıları herhangi gerçekleşmesi için

, anket() en azından zaman aşımı milisaniye beklemek zorundadır. Zaman aşımının değeri 0 ise,() hemen döndürecektir. zaman aşımının -1 değeri ise, aranan bir olay gerçekleşene kadar arama (+), çağrı kesilene kadar engellenir.

struct pollfd stdin_poll = { .fd = STDIN_FILENO 
          , .events = POLLIN | POLLRDBAND | POLLRDNORM | POLLPRI }; 
if (poll(&stdin_poll, 1, 0) == 1) { 
    /* Data waiting on stdin. Process it. */ 
} 
/* Do other processing. */ 
İlgili konular