Newsgroup: it.comp.programmare
Titolo: bufferizzazione I/O

Ciao,
cerco un modo per disabilitare la bufferizzazione dello stdin sotto
Linux.
Ho letto che bastava usare la funzione setbuf(stdin, NULL); ma non mi
funziona!
Il mio scopo č quello di far sě che appena l'utente tocca un tasto il
prg se ne accorga, senza aspettare la pressione di INVIO. Come posso
fare?
Incollo qui il programmino che ho scritto di prova ma che non ottiene il
risultato desiderato: l'utente deve premere invio perché il prg
funzioni!
/*
 * Prova di uso getchar
 */
#include<stdio.h>
int main()
{
	char appoggio;
 
	setbuf(stdin, NULL);
 
	printf("\nimmetti un carattere: ");
	appoggio = getchar();
	printf("\nIl carattere č: %c", appoggio);
 
	return(0);
}
grazie 1000 dell'aiuto.
Ciao,
-- 
    Riccardo
-=# 2.000.000 lemmings cannot be wrong #=-

 fare?
Devi dire al driver del terminale che non vuoi il suo normale
servizio di input "cucinato" ("cooked") -- quello che permette
normalmente a un utente di cancellare un carattere battuto per
errore, ecc -- e vuoi invece "input crudo".
Ecco un classico esempio di Mumit Khan (che lo prese a sua
volta dal classicissimo Stevens) visto in termini di una
implementazione dei tradizionali 'kbhit' e 'getch' del DOS
su un generico sistema POSIX (Linux incluso).  Ho solo
tradotto i commenti...
/* kbhit.c -- esempio di implementazione di kbhit/getch */
#include <stdio.h>
#include <sys/time.h>
#include <termios.h>
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
/* Usa raw-mode solo se sai come gestire segnali eccetera!!! */
#ifdef USE_RAW_MODE
# define RAW_MODE(x) tty_raw((x))
#else
# define RAW_MODE(x) tty_cbreak((x))
#endif
static struct termios save_termios;
static int
tty_cbreak (int fd)
{
  struct termios ios;
  if (tcgetattr (fd, &save_termios) < 0)
    return -1;
  ios = save_termios;
  ios.c_lflag &= ~(ICANON | ECHO);
  ios.c_cc[VMIN] = 1;
  ios.c_cc[VTIME] = 0;
  return tcsetattr (fd, TCSAFLUSH, &ios);
}
static int
tty_raw (int fd)
{
  struct termios ios;
  if (tcgetattr (fd, &save_termios) < 0)
    return -1;
  ios = save_termios;
  ios.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG);
  ios.c_lflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  ios.c_lflag &= ~(CSIZE | PARENB);
  ios.c_lflag |= CS8;
  ios.c_lflag &= ~(OPOST);
  ios.c_cc[VMIN] = 1;
  ios.c_cc[VTIME] = 0;
  return tcsetattr (fd, TCSAFLUSH, &ios);
}
static int
tty_reset (int fd)
{
  return tcsetattr (fd, TCSAFLUSH, &save_termios);
}
int
kbdhit (void)
{
  fd_set rfds;
  struct timeval tv;
  /* Esamina stdin (fd 0) per vedere se ha input */
  FD_ZERO (&rfds);
  FD_SET (STDIN_FILENO, &rfds);
  /* Return immediately. */
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  /* Funziona solo se e` gia` in modo raw o cbreak! */
  return select (STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) &&
    FD_ISSET (STDIN_FILENO, &rfds);
}
int
getch (void)
{
  int c;
  /* Funziona solo se e` gia` in modo raw o cbreak! */
  if (read (STDIN_FILENO, &c, 1) != 1)
    c = EOF;
  return c & 0xff;
}
int
main ()
{
  int i;
  char c;
  puts ("Batti Q per terminare... ");
  fflush (stdout);
  RAW_MODE (STDIN_FILENO);
  while (1)
    {
      fputs ("Dormo 2 secondi ... ", stdout);
      fflush (stdout);
      sleep (2);
      fputs ("sono sveglio! Controllo la tastiera\n", stdout);
      fflush (stdout);
      if (kbdhit ())
 {
   int c;
   fputs ("si` ... ", stdout);
   fflush (stdout);
   c = getch ();
   fprintf (stdout, "%c\n", c);
   fflush (stdout);
   if (c == 'q' || c == 'Q' || c == EOF)
     break;
 }
      fputs ("No. Torno a nanna\n", stdout);
    }
  tty_reset (STDIN_FILENO);
  puts ("\nFinito.");
  return 0;
}
Alex (MVP di Brainbench per il C++)