Vai al contenuto

[C] Ricevere un carattere da tastiera asincrono e stamparlo su schermo


Messaggi raccomandati

Ciao a tutti! Sto cercando di scrivere un programma in cui, dopo aver messo la funzione main() in pausa (con la chiamata di sistema pause()), se l'utente preme un qualsiasi tasto sulla tastiera il programma lo riconosce e stampa su schermo una frase del tipo "Hai premuto il pulsante 'x'". Ho provato a cercare su internet ma l'unica cosa che sono riuscito a trovare è come riconoscere se l'utente ha premuto ctrl-c. Vi inserisco anche il codice che ho scritto, sperando che vi possa essere d'aiuto a capire il mio problema. Grazie a tutti in anticipo!

 

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

void catch_keyboard(int signo) {
    char c;
    read(STDIN_FILENO, &c, 1);
    printf("Pressed %c on keyboard\n", c);
}

void sig_quit() { //chiude il programma quando riconosce la combinazione ^\
    exit(0);
}

int main() {
    signal(SIGIO, catch_keyboard);
    signal(SIGQUIT, sig_quit);
    pause();
}

 

Link al commento
Condividi su altri siti

da quel che vedo nel tuo programma è chiaro che usi la pause ma non hai capito cosa fa esattamente.

Usando pause() il tuo programma andrà in pausa fino a che non riceverà un segnale... ctrl-c è uno dei segnali di default di Unix SIGINT:

https://en.wikipedia.org/wiki/Unix_signal

e serve ad interrompere il programma.

 

Se vuoi semplicemente stampare l'input dell'utente c'è un modo molto, molto più semplice (che non fa uso di system call) per fare il tutto (aspettando tra l'altro l'input dell'utente):

#include <stdio.h>

int main() {
    char c = '\0';
    c = getchar();
    printf("Pressed %c on keyboard\n", c);
}

 

c = '\0' serve ad inizializzare la variabile char in modo che sia pulita (in c è sempre meglio inizializzare le variabili per essere sicuri che il loro contenuto sia quello voluto).

getchar() ferma il programma finchè non riceve invio dall'utente.

mettendo quel che abbiamo ottenuto dentro c, possiamo poi stamparla a video con printf.

 

Se la tua intenzione era però usare delle system call, inizia a studiare come funziona la fork.

Link al commento
Condividi su altri siti

Grazie per la risposta Lief. Non so se così possa funzionare, ti spiego brevemente la mia idea: vorrei realizzare un programma multithreading nel quale con un thread gestisco la generazione di una forma d'onda e la sua uscita alle casse, con un altro invece vorrei gestire l'interazione con l'utente (ogni lettera corrisponde ad una nota, per cui viene generata la forma d'onda solo quando l'utente preme un tasto e interrompe la sua produzione solo nel momento in cui la tastiera non riceve più pressioni). Cercando ancora su internet ho trovato una soluzione che mi soddisfa a metà... Usare la libreria <termios.h>. Purtroppo da quanto ho capito se volessi utilizzare il terminale mentre il mio programma è in esecuzione sarebbe impossibile, per cui sto cercando altre soluzioni (sempre che esistano). Vorrei evitare di creare un altro processo con la fork visto il peso che andrebbe la sua creazione... Spero tu possa aiutarmi..

Link al commento
Condividi su altri siti

la programmazione multithread in C non l'ho mai usata, l'ho usata solo in Java, mentre in C ho fatto solo programmazione multiprocesso con fork. In ogni caso non devi pensare che sia una cosa negativa la creazione di uno o più processi figli (se il tuo scopo è far lavorare più processi in contemporanea), se una cosa serve e vale la "spesa" si fa... Se si può fare meglio si fa meglio.

I thread comunque si basano all'incirca sugli stessi principi... Studiando un po' come funziona la fork sono convinto che capirai anche meglio i thread.

La soluzione che ti ho segnalato la puoi comunque integrare all'interno del tuo codice (sempre se vuoi fare tutto da linea di comando ovviamente...), resta il metodo più semplice in assoluto per leggere l'input di un utente da terminale e non mi sembra necessario inventare nulla di diverso per il tuo problema (un codice semplice si mantiene meglio ed è sempre meglio restare sul semplice se possibile).

Per quanto riguarda il resto del programma non saprei proprio aiutarti. Non ho mai fatto nulla del genere, non mi viene in mente neanche da dove iniziare.

Sicuramente la cosa migliore è cercare qualche codice d'esempio funzionante e studiare le singole parti (anche se non fa esattamente quel che vuoi può comunque darti indizi utili per arrivare alla soluzione).

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...