Codice: Seleziona tutto
cout << "un tasto non stampabile" << endl;
Codice: Seleziona tutto
printf ("0x%x\n", int(c));
Dopodiché invece di farci uno switch ci fai un minuscolo automa a stati finiti.
Saluti
Codice: Seleziona tutto
cout << "un tasto non stampabile" << endl;
Codice: Seleziona tutto
printf ("0x%x\n", int(c));
Codice: Seleziona tutto
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <termios.h>
#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;
// Per pulizia ho raccolto il codice relativo a termios in una classe
class termiosModifier {
termios before, after;
public:
termiosModifier () {
tcgetattr (STDIN_FILENO, &before);
after = before;
after.c_lflag &= (~ICANON);
after.c_lflag &= (~ECHO);
tcsetattr (STDIN_FILENO, TCSANOW, &after);
}
~termiosModifier () {
tcsetattr (STDIN_FILENO, TCSANOW, &before);
}
};
// per pulizia ho raccolto il codice relativo alla select in una classe
class selectWrapper {
fd_set rfds0;
int maxfd;
struct timeval tv;
public:
selectWrapper () {
FD_ZERO (&rfds0);
FD_SET (STDIN_FILENO, &rfds0);
maxfd = STDIN_FILENO;
}
~selectWrapper () {
}
int waitForKey (char & c) throw (runtime_error) {
// con 1 secondo il serpente sara' lento
// prova a mettere tv.tv_sec = 0; tv.tv_usec = 100000; (1/10 di secondo)
tv.tv_sec = 1;
tv.tv_usec = 0;
fd_set rfds = rfds0;
int nready = select (maxfd + 1, &rfds, 0, 0, &tv);
if (nready < 0) {
ostringstream message;
message << "errno = " << errno << ends;
throw runtime_error (message.str ());
}
if (nready > 0) {
if (FD_ISSET (STDIN_FILENO, &rfds)) {
read (STDIN_FILENO, &c, 1);
}
else {
throw runtime_error ("dovrebbe esserci qualcosa ma non c'e'");
}
}
return nready;
}
};
// Questo e' l'automa a stati finiti
class eventGetter {
selectWrapper sw;
public:
typedef enum {
TIMEOUT,
LEFT_ARROW,
RIGHT_ARROW,
DOWN_ARROW,
UP_ARROW,
PRINTABLE,
INCOMPLETE
} eventType;
private:
// Gli stati dell'automa sono queste tre funzioni
eventType awaitingAnyChar (char & c) throw (runtime_error) {
// stato base, accetto qualsiasi cosa
for (;;) {
if (sw.waitForKey (c) == 0) return TIMEOUT;
if (c == '\e') {
currentState = &eventGetter::gotEsc;
return INCOMPLETE;
}
if (isprint (c)) return PRINTABLE;
// carattere non stampabile diverso da ESC: lo filtro
}
}
eventType gotEsc (char & c) throw (runtime_error) {
// ho gia' visto ESC, aspetto solo [ (altre possibilita' da aggiungere)
if (sw.waitForKey (c) == 0) {
throw runtime_error ("Timeout a meta' sequenza: com'e' possibile?");
}
if (c == '[') {
currentState = &eventGetter::gotEscOpensquare;
return INCOMPLETE;
}
// Qualsiasi altro carattere non lo so ancora gestire
throw runtime_error ("Questa sequenza mi e' ancora sconosciuta.");
}
eventType gotEscOpensquare (char & c) throw (runtime_error) {
// ho visto ESC[ e adesso mi aspetto A, B, C oppure D
if (sw.waitForKey (c) == 0) {
throw runtime_error ("Timeout a meta' sequenza: com'e' possibile?");
}
switch (c) {
case 'A':
currentState = &eventGetter::awaitingAnyChar;
return UP_ARROW;
case 'B':
currentState = &eventGetter::awaitingAnyChar;
return DOWN_ARROW;
case 'C':
currentState = &eventGetter::awaitingAnyChar;
return RIGHT_ARROW;
case 'D':
currentState = &eventGetter::awaitingAnyChar;
return LEFT_ARROW;
default:
throw runtime_error ("Questa sequenza mi e' ancora sconosciuta.");
}
}
// Questo e' il puntatore allo stato corrente
eventType (eventGetter::*currentState) (char & c) throw (runtime_error);
public:
eventGetter () {
currentState = &eventGetter::awaitingAnyChar;
}
~eventGetter () {
}
eventType getNextEvent (char & c) throw (runtime_error) {
for (;;) {
eventType event = (this->*currentState) (c);
if (event != INCOMPLETE) return event;
}
}
};
int main () {
try {
termiosModifier tm;
eventGetter eg;
for (;;) {
char c;
eventGetter::eventType event = eg.getNextEvent (c);
switch (event) {
case eventGetter::TIMEOUT:
cout << "TIMEOUT: ne approfitto per ridisegnare il serpente" << endl;
break;
case eventGetter::LEFT_ARROW:
cout << "LEFT_ARROW: il serpente va a sinistra" << endl;
break;
case eventGetter::RIGHT_ARROW:
cout << "RIGHT_ARROW: il serpente va a destra" << endl;
break;
case eventGetter::UP_ARROW:
cout << "UP_ARROW: il serpente va su" << endl;
break;
case eventGetter::DOWN_ARROW:
cout << "DOWN_ARROW: il serpente va giu'" << endl;
break;
case eventGetter::PRINTABLE:
cout << "carattere stampabile: " << c << endl;
if (c == 'z') {
cout << "ciao" << endl;
return 0;
}
break;
}
}
}
catch (runtime_error & err) {
cerr << err.what () << endl;
}
return 0;
}
Codice: Seleziona tutto
...
else if (FD_ISSET (STDIN_FILENO, &rfds)) {
read (STDIN_FILENO, &move, 1);
if (isprint (move)){
if (move == 'z') {
tcsetattr (STDIN_FILENO, TCSANOW, &before);
break;
}
//if (!beboop.make_move (move)){
//tcsetattr (STDIN_FILENO, TCSANOW, &before);
//break;
//}
}
Codice: Seleziona tutto
const int sampling = 100000; // microsecondi
Codice: Seleziona tutto
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = sampling;
Codice: Seleziona tutto
int elapsed = 0; // tempo trascorso dall'ultimo aggiornamento del serpente in microsecondi
Codice: Seleziona tutto
struct timeval before_select, after_select;
gettimeofday (&before_select, 0);
Codice: Seleziona tutto
gettimeofday (&after_select, 0);
// Per generalita' converto tutto in us, anche se tv_sec dovrebbe sempre essere 0
elapsed += (after_select.tv_sec * 1000000 + after_select.tv_usec);
elapsed -= (before_select.tv_sec * 1000000 + before_select.tv_usec);
if (elapsed >= sampling) {
beboop.make_move (move);
elapsed -= sampling;
}
Codice: Seleziona tutto
if (nready == 0) {
//if (!beboop.make_move (move)){
//tcsetattr (STDIN_FILENO, TCSANOW, &before);
//break;
//}
}
Codice: Seleziona tutto
#include <stdio.h>
#include <ncurses.h>
int main() {
int c;
c = getch();
printf("\nValore c: %d \n",c);
}
Codice: Seleziona tutto
#include <stdio.h>
#include <ncurses.h>
int main() {
int c;
initscr ();
cbreak ();
noecho ();
c = getch();
printw("\nValore c: %d \n",c);
printw ("premi un tasto per uscire da ncurses\n");
getch ();
endwin ();
}
Ashura ha scritto: mioddio... ma come fai a sostenere che quella roba sia C++?
scrivere un programma in C, usando le iostream e salvare il file con estenzione .cpp non significa sviluppare in C++ eh...
semplicemente in questo modo compilerai il tuo codice C col compilatore C++...
Beh considerando che il C++ e` multiparadigma e che incorpora la libreria standard C nella propria, non posso dirmi proprio d'accordo con quanto quotatoAshura ha scritto: mioddio... ma come fai a sostenere che quella roba sia C++?
scrivere un programma in C, usando le iostream e salvare il file con estenzione .cpp non significa sviluppare in C++ eh...
[...]
Una curiosità... non m'ero accorto di usare le iostream... dov'è che le uso?Ashura ha scritto: mioddio... ma come fai a sostenere che quella roba sia C++?
scrivere un programma in C, usando le iostream e salvare il file con estenzione .cpp non significa sviluppare in C++ eh...
Visualizzano questa sezione: 0 utenti iscritti e 9 ospiti