Newsgroup: it.comp.programmare
Titolo: [Aiuto - C] Funzione kbhit su linux: come fare?

Ciao a tutti
sto facendo un programma in C su linux e non so come rendere la funzione 
kbhit(), per terminare l'esecuzione premendo un tasto senza usare ctrl+C.
In rete ho trovato un "kbhit.h" di poche righe, ma io volevo usare solo 
quello che fornisce l'ANSI C anche per motivi di portabilita linux/windows.
Qualcuno puo aiutarmi per favore?
Grazie e ciao. 

cristina ha scritto:

In due parole: in modalita' diretta non si puo'!
kbhit() e' una funzione definita in conio.h, propria di ambienti DOS, 
con interfaccia di console e lettura diretta della tastiera.
Unix invece utilizza come interfaccia il terminale e legge 
convenzionalmente dallo stdin, di conseguenza non ha senso l'attesa di 
un tasto, specialmente se a questo tasto non corrisponde un carattere.
Puoi tuttavia ottenere qualcosa di molto simile utilizzando la libreria 
curses, che riesce ad incapsulare molte delle funzioni di conio.
curses e' tranquillamente supportata da tutte le installazioni di 
unix/linux dalla notte dei tempi.
Non ho tuttavia idea se lo sia anche sotto windows, anche perche' 
avrebbe ben poco senso usare curses in un sistema operativo grafico di 
per se.

 per se.
Ha senso invece, e ci sono un paio di porting delle ncurses per Windows.
Saluti  Manlio Perillo

>
le curses le ho scartate (perche non le so usare :P) ma anche per 
portabilita del codice 

 Ha senso invece, e ci sono un paio di porting delle ncurses per Windows.
Non dubito che ci siano, anzi, sarei stupito del contrario.
Pero' mi lascia perplesso l'effetto che possa avere una finestra in
ascii art all'interno di una finestra di cmd per un utente abituato alle
classiche finestre di windows.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 
Eccoti la versione in Python (sono troppo pigro per scriverti la versione
in C):
#!/usr/bin/env python
def unix_kbhit():
    import termios, sys, select, tty
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    try:
        tty.setraw(fd, termios.TCSADRAIN)
        select.select([fd], [], [])
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)
if __name__ == '__main__':
    kbhit()
In questo caso quello che hai da fare è usare la kbhit di conio se sei su
Windows e questa se sei su un sistema POSIX.
Per vedere come mettere un file in modalità raw, dai una occhiata a:
http://svn.python.org/view/python/trunk/Lib/tty.py?view=markup
Non sono un esperto di terminali, devo confessare di ignorare il
significato di tutti quei parametri...
Saluti  Manlio Perillo

 
Capisco, ti riferivi a questo.
Ma all'OP, comunque, interessa solo sapere quando l'utente preme un tasto,
non scrivere una gui completa.
Saluti  Manlio Perillo

 portabilita del codice 
Con le ncurses dovrebbe essere decisamente portabile.

 
Questo esempio mi ha ispirato una ricerca su google e ho trovato questa
pagina
http://www.pwilson.net/kbhit.html
Nell'esempio indicato vengono modificate le terminal capabilities
impostando il raw mode del terminale, i timeout e quanto serve per poter
attendere la pressione di un tasto senza l'echo.
Non sono riuscito a capire se nel codice di esempio viene salvato lo
stato delle terminal capabilities prima dell'attesa.
Ad ogni modo devi trappare tutte le signal perche' se il processo viene
killato mentre e' in attesa del tasto, con la configurazione del
terminale modificata, si incasina tutto!
Quindi la procedura corretta da adottare e':
1) salvare lo stato del terminale
2) modificarlo per poter attendere un tasto tipo kbhit
3) ripristinare lo stato del terminale
4) nel trap dei segnali ripristinare lo stato del terminale
Mi pare non ci sia altro, spero...
