2012-12-29 8 views
5

मैं सी में ncurses का उपयोग कर रहा वर्तमान समय (समय प्रत्येक दूसरे को अपडेट करना होगा) दिखाने के लिए एक खेल को लागू करने की कोशिश कर रहा हूँ और मेरी जबकि पाश इसncurses और वास्तविक समय (सी में लागू किया, यूनिक्स)

तरह लग रहा है
while(1) 
{ 
    clk = time(NULL); 
    cur_time = localtime(&clk); 
    mvprintw(0,1,"%d %d %d",cur_time->tm_hour,cur_time->tm_min,cur_time->tm_sec); 
    int key = getch() 
    //other stuff 
} 

मेरी समस्या यह है कि जब मैं एक कुंजी दबाता हूं तो समय ताज़ा हो जाएगा। क्या यह एक कुंजी दबाए जाने के बिना समय को रीफ्रेश करने का एक तरीका है (और इसे एक ही समय में लागू करने के लिए)?

+1

समस्या stdin पर अवरुद्ध I/O में है। आपको नॉनबॉकिंग I/O का उपयोग करने के लिए एक तरीका चाहिए। (मुझे नहीं पता कि (एन) शाप नॉनब्लॉकिंग I/O का उपयोग करने का कोई तरीका लागू करते हैं। मुझे लगता है कि यह करता है) – wildplasser

+1

(प्रयोगात्मक) फ़ंक्शन wgetch_events() आपकी आवश्यकताओं को भरने लगता है। (नोट: मैंने कभी इसका इस्तेमाल नहीं किया, मैंने इसे ncurses.h में देखा।) – wildplasser

उत्तर

4

कार्यों की एक जोड़ी आप इस्तेमाल कर सकते हैं कर रहे हैं:

  1. nodelay
  2. टाइमआउट

पूर्णांक nodelay (खिड़की * जीत, bool BF के);

सेट BF के getch() गैर-अवरुद्ध बनाने के लिए सच

शून्य टाइमआउट (पूर्णांक देरी);

देरी मिलीसेकंड में है, इसलिए यदि आप इसे 1000 तक सेट करते हैं, तो गेट एक सेकंड के बाद टाइमआउट करेगा।

यदि कोई इनपुट नहीं है तो दोनों मामलों में गेट ईआरआर वापस कर देगा।

1

यहां समाधान गैर-अवरुद्ध आईओ या धागे का उपयोग करने के लिए है। हालांकि, धागे का उपयोग करने से आपको एक नई समस्या मिल जाएगी, जो कि केवल एक धागा किसी भी समय शाप का उपयोग कर सकता है, इसलिए आपको उस बिंदु पर शापों का उपयोग करने से अन्य धागे को रोकने के लिए ताले या कुछ ऐसे उपयोग करने की आवश्यकता होगी पहर। बेशक, इसके लिए एक समाधान स्क्रीन सामग्री को अपडेट करने के लिए एक थ्रेड जिम्मेदार होना है, और अन्य धागे बस उस धागे को संदेश भेजते हैं, "मैं एक्स, वाई पर स्क्रीन डालना चाहता हूं"

0

यह बहुत है बदसूरत हैक जो सिर्फ एक एकल stdio समारोह का समर्थन करता है: fgetc()। अन्य जोड़ा जा सकता है, बीटीडब्ल्यू। यह टाइमर सेट करके काम करता है, अगर एक वर्ण को पढ़ने से पहले अलार्म बंद हो जाता है, तो एक -2 मान वापस लौटाया जाता है (याद रखें: -1 मतलब ईओएफ)

यह काम नहीं करेगा अन्य शाप के wgetXXX(), फ़ंक्शंस, जो fgetc() (आदि) को सीधे कॉल कर सकते हैं। YMMV।

लेकिन, सामान्य मामले में, मुझे लगता है कि आपको wgetch_events() की जांच करनी चाहिए।

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <signal.h> 
#include <setjmp.h> 

sigjmp_buf the_jump; 

int my_fgetc(FILE *fp, unsigned timeout); 
void sig_handler(int signr); 

void sig_handler(int signr) { 
     switch (signr) { 
     case SIGALRM: 
       siglongjmp(the_jump,1); 
       break; 
     default: 
       break; 
     } 
} 

int my_fgetc(FILE *fp, unsigned timeout) 
{ 
alarm(timeout); 

switch (sigsetjmp(the_jump, -1)) { 
case 0: 
     alarm(0); 
     return fgetc (fp); 
case 1: 
     return -2; 
default: 
     return -3; 
     } 
} 

int main() 
{ 
int rc; 
signal(SIGALRM, sig_handler); 

rc = setvbuf(stdin, NULL, _IONBF, 0); 
printf("setvbuf(_IONBF) = %d\n", rc); 
while (1) { 
     rc = my_fgetc(stdin, 1); 
     printf("my_fgetc(NULL) = %d\n", rc); 
     } 

return 0; 
} 
+0

यह छेद से भरा है। सबसे पहले, आप चरित्र प्राप्त करने के बाद अलार्म को रीसेट नहीं करते हैं, इसलिए कुछ प्रोसेसिंग करते समय अलार्म बंद हो सकता है, और आप सीधे वापस my_getc पर कूदते हैं, स्टैक के साथ और सबकुछ उस कोड पर वापस सेट होता है - खराब चीजें निश्चित रूप से होती हैं क्या तुम्हें यह आता है। फिर आपके पास fgetc से लौटने और अलार्म बंद होने के बीच एक दौड़ है। निश्चित रूप से, यह ज्यादातर समय काम कर सकता है, लेकिन इसे थोड़ी देर के लिए चल रहा है, इसके माध्यम से कुछ अक्षर चलाएं, और यह गिर जाएगी, गारंटीकृत। –

+0

यह सही है। यह केवल एक प्रदर्शन के रूप में इरादा था। हैंडलर को सिग्नेक्शन() के माध्यम से रेस फ्री भी स्थापित किया जाना चाहिए। एक दूसरी समस्या समस्या शाप/टर्मियो के साथ संभवत: एस्केप-स्ट्रिंग के समय के लिए 5 सेकंड देरी का उपयोग कर रही है। (वास्तविक अनुक्रम की शुरुआत से एक नंगे ईएससी को अलग करने के लिए)।एनबी: मैंने केवल अलार्म (0) जोड़ने के लिए अद्यतन किया; – wildplasser

+0

चूंकि ओपी पहले से ही ncurses का उपयोग करता है, इसलिए कुर्सियों के गैर-अवरुद्ध पढ़ने के लिए ncurses में कई तरीके हैं (इसमें टाइमआउट() फ़ंक्शन भी है)। या आप टाइमआउट पर, stdin पर केवल() या poll() का उपयोग कर सकते हैं। – nos

संबंधित मुद्दे