2013-08-17 36 views
5

Chúng tôi biết chức năng đầu vào hoặc toán tử (cin, scanf, được… .etc) chờ để nhận người dùng biểu mẫu đầu vào & lần này không có giới hạn.Làm thế nào để tắt câu lệnh nhập sau một thời gian?

Bây giờ, tôi sẽ đặt câu hỏi & người dùng đưa ra câu trả lời, cho đến bây giờ không có vấn đề nhưng vấn đề của tôi là "người dùng có thời gian (có thể 30 hoặc 40 giây) để cung cấp cho đầu vào. tự động hủy kích hoạt & thực hiện câu lệnh tiếp theo. ”

Tôi nghĩ bạn gặp vấn đề của tôi. Sau đó, hãy giúp tôi trong tình huống này. Sẽ tốt hơn nếu ai đó đưa cho tôi một số mã ví dụ thực sự làm việc.

tôi sử dụng codebolck 12,11 trong cửa sổ 7.

+4

Chuẩn C++ không có gì để giúp bạn. Bạn cần phải sử dụng một số thủ thuật dành riêng cho hệ điều hành nhiều hơn hoặc ít hơn. –

+1

cảm ơn câu trả lời của bạn. Bạn có thể cho tôi một loại ví dụ hoặc chức năng nào không? – Xplosive

+0

Không, bởi vì tôi không biết hệ điều hành của bạn là gì. –

Trả lời

10

Một cách tiếp cận cho hệ thống * IX'ish (bao gồm Cygwin trên cửa sổ):

Bạn có thể sử dụng alarm() để sắp xếp một SIGALRM, sau đó sử dụng read(fileno(stdin), ...).

Khi tín hiệu đến read() sẽ trở về với -1 và đã đặt errno thành EINTR.

Ví dụ:

#define _POSIX_SOURCE 1 

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <signal.h> 
#include <errno.h> 

void handler_SIGALRM(int signo) 
{ 
    signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */ 

    /* Do nothing. */ 
} 

int main() 
{ 
    /* Override SIGALRM's default handler, as the default handler might end the program. */ 
    { 
    struct sigaction sa; 
    memset(&sa, 0, sizeof(sa)); 

    sa.sa_handler = handler_SIGALRM; 

    if (-1 == sigaction(SIGALRM, &sa, NULL)) 
    { 
     perror("sigaction() failed"); 
     exit(EXIT_FAILURE); 
    } 
    } 

    alarm(2); /* Set alarm to occur in two seconds. */ 

    { 
    char buffer[16] = { 0 }; 

    int result = read(fileno(stdin), buffer, sizeof(buffer) - 1); 
    if (-1 == result) 
    { 
     if (EINTR != errno) 
     { 
     perror("read() failed"); 
     exit(EXIT_FAILURE); 
     } 

     printf("Game over!\n"); 
    } 
    else 
    { 
     alarm(0); /* Switch of alarm. */ 

     printf("You entered '%s'\n", buffer); 
    } 
    } 

    return EXIT_SUCCESS; 
} 

Lưu ý: Trong ví dụ trên lệnh gọi chặn để read() sẽ được interupted trên bất kỳ tín hiệu đến. Các mã để tránh điều này là trái như một execise để người đọc ... :-)

2

Một Phương pháp:
Bạn có thể sử dụng POSIX select() chức năng (và một số macro FD_ZERO, FD_SET, FD_ISSET) để kiểm tra tập tin mô tả (số mô tả 0 tức là stdin, trong trường hợp này) đã sẵn sàng để được đọc trong một khoảng thời gian nhất định. Khi họ đã sẵn sàng, sử dụng chức năng thích hợp để đọc dữ liệu (scanf() trong trường hợp này).
Mã này có thể giúp bạn hiểu, những gì tôi muốn nói:

#include <sys/select.h> 
#include <sys/time.h> 
#include <stdio.h> 

#define STDIN 0 // Standard Input File Descriptor 
int main() 
{ 
    fd_set input;  // declare a "file descriptor set" to hold all file descriptors you want to check 
    int fds, ret_val, num; // fds: Number of file descriptors; 

    struct timeval tv;  // structure to store Timeout value in the format used by select() function 
    unsigned int timeout = 5; // Your timeout period in seconds 

    tv.tv_sec = timeout;  
    tv.tv_usec = 0; 

    fds = STDIN + 1;   // Set number of file decriptors to "1 more than the greatest file descriptor" 
       // Here, we are using only stdin which is equal to 0 

    FD_ZERO(&input);  // Initialize the set with 0 
    FD_SET(STDIN, &input);  // Add STDIN to set 

    printf("Enter a number within %d secs\n", timeout); 
    ret_val = select(fds, &input, NULL, NULL, &tv); 
       // We need to call select only for monitoring the "input file descriptor set" 
       // Pass rest of them as NULL 

    if (ret_val == -1)   // Some error occured 
     perror("select()"); 
    else if (ret_val > 0)  // At least one of the file descriptor is ready to be read 
    { 
//  printf("Data is available now.\n"); 
     if(FD_ISSET(0, &input))  // Check if stdin is set, here its not necessary as we are using STDIN only 
       // So ret_val>0 means STDIN is raedy to read 
     { 
      scanf("%d", &num); 
     } 
    } 
    else 
     printf("No data within five seconds.\n"); // select returns zero on timeout 

    return 0; 
} 

Help: select(2)

Bạn cũng có thể thử sử dụng) chức năng (bình chọn có sẵn trong (một lần nữa một chức năng tiêu chuẩn POSIX) như một thay thế cho select(). Xem poll() & poll(2)

+3

Tôi chỉ muốn đưa ra đề xuất tương tự. (Đôi khi bạn có thể muốn xử lý EINTR tại mệnh đề 'ret_val == -1'.) Để chuyển đổi điều này sang Windows, hãy xem câu hỏi này: http://stackoverflow.com/q/933745/1025391 – moooeeeep

+0

Cảm ơn @moooeeeep cho liên kết !! Tôi cũng tự hỏi làm thế nào mã tương tự có thể làm việc theo hệ thống dựa trên Windows. Tôi quên đề cập đến điều này không có tính di động trong câu trả lời của tôi. –

+1

#include #include trình biên dịch của tôi không thể tìm thấy tệp tiêu đề như vậy. tôi sử dụng codebolck 12.11 – Xplosive

0
#include <cstddef> 
#include <ctime> 
#include <iostream> 
#include <conio.h> 

bool get_input (char *buffer, std::size_t size, int timeout) 
{ 
    std::time_t start = std::time (0); 
    std::size_t n = 0; 

    for (; ;) { 
    if (n == 0 && std::difftime (std::time (0), start) >= timeout) 
    return false; 

    if (kbhit()) { 
    if (n == size - 1) 
    break; 

    char ch = (int)getche(); 

    if (ch == '\r') { 
    buffer[n++] = '\n'; 
    break; 
    } 
    else 
    buffer[n++] = ch; 
    } 
} 

buffer[n] = '\0'; 

return true; 
} 

int main() 
{ 
char buffer[512] = {0}; 

if (!get_input (buffer, 512, 5)) { 
std::cout<<"Input timed out\n"; 
buffer[0] = '\n'; 
} 

std::cout<<"input: \""<< buffer <<"\"\n"; 
} 
+1

thử chương trình này hoạt động tốt của nó – Akshay

+0

tôi chạy mã này trong khối mã 13.2 làm việc tốt của nó sau một khoảng thời gian chương trình kết thúc tự động bằng cách sử dụng mã này là có bất kỳ có thể sử dụng nó cho cin ???? – Akshay

+0

Mã này sử dụng chức năng phi tiêu chuẩn-C, không POSIX, và với điều này là không thể chuyển đổi cao. – alk

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