Newsgroup: it.comp.lang.c
Titolo: Beh... allora chiediamola tutta... (gets e malloc)

si parlava dell'input da tastiera in un mio precedente post...
innanzi tutto ringrazio per i post di risposta.. non mi aspettavo di
scatenare una cosi' accesa disputa :)
son al mio primo programma "serio" ... finora ho solo fatto programmini
semplici oppure ho rimaneggiato programmi di altri (anche abbastanza
complessi)
ho lavorato molto con le socket... ma in input locale mai.. ed ecco che
saltano fuori i problemi... come gia' diceva alex... mi si pone il
problema che l'input che passo al mio programma(classica domanda s/n)
da stdin non viene flushato... in poche parole... se io scrivo alla
domanda questo:
sferhgtdhthg
mi fa il getchar e mi prende il s
mentre il rimanente "ferhgtdhthg" mi resta come input successivo alla
domanda che viene dopo... cosa devo fare?la cos che mi e' sembrata molto
semplice (ma non provata ad essere sincero) e' chiudere lo stdin e poi
riaprirlo... non esiste n qualcosa per flushare lo stdin prima di fare una
nuova richiesta di input?
				Grazie! :)
 ---------------------------
quela:~# mount -t vfat /dev/hda1 /windows
mount: error mounting /dev/hda1... mmmh...It's full of rubbish !!
Try this instead:     mke2fs -c /dev/hda1 <block size>
It will work better !
---------------------------
                                          Stefano Borini

 
Non puoi chiudere e riaprire stdin e compari in quanto non hai il nome
del file corrispondente che addirittura potrebbe non esistere
fisicamente. hai pero' una funzione che si chiama 'fflush' per svuotare
il buffer, leggiti pero' la documentazione e fai un po' di prove perche'
potrebbe funzionare in maniera alquanto strana.
Marco


mmm... sicuro?
mi sembra di ricordare che fflush sia definita per file di output, applicarla
ad un file di input da' il funzionamento anomalo di cui parlavi.
Emanuele
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp
   Create Your Own Free Member Forum

 
mea culpa,
un rapido 'man fflush' su Digital ha confermato cio': Digital parla di
fflush solo a proposito di file in scrittura.
Comunque provare non costa nulla
Marco

In effetti, anche io avevo trovato la funzione fflush, ma da pagina di
manuale risultava che forzava il flush dei dati sull'output... quindi
probabilemente non funziona sul mio problema...
ad ogni modo proseguo nella ricerca... non vorrei trovarmi a fare un
getchar ricorsivo fino a svuotare lo stdin... mi sembrerebbe abbastanza
stupido per un linguaggio evoluto come il C...
dai su... non obbligatemi ad imparare il C++ :)) (linguaggio che comunque
presto studiero'... piu' linguaggi so piu' mi diverto)
					grazie ancora


 					grazie ancora
Si puo' eliminare la bufferizzazione
setbuf(3)                                                           setbuf(3)
NAME
  setbuf, setvbuf, setvbuf_unlocked, setbuffer, setlinebuf - Assign buffering
  to a stream
LIBRARY
  Standard C Library (libc.so, libc.a)
Si puo' usare la libreria ncurses
___________________________________________________________________________
                       Get Family (Get Input from Keyboard to Window)
  [mv][w]getch         Get a character                                  Y Y Y
  [mv][w]get[n]str     Get a character string                           Y Y Y
  [mv][w]get_wch       Get a wide character                             Y Y Y
  [mv][w]get[n]_wstr   Get an array of wide characters and key codes    Y Y Y
  ___________________________________________________________________________

Borini Stefano (
stu2528@NOSPAM_ME_OR_ILL_BOMB_YOU.student.unife.it
) wrote:
[ snip ]
: ad ogni modo proseguo nella ricerca... non vorrei trovarmi a fare un
: getchar ricorsivo fino a svuotare lo stdin... mi sembrerebbe abbastanza
: stupido per un linguaggio evoluto come il C...
Evoluto ? Non credo che il C possa definirsi 'evoluto' come linguaggio,
e questo e' pure il suo piu' grande vantaggio, IMHO. In ogni caso, qual'e'
il problema nello svuotarsi la coda di input a mano ?
: dai su... non obbligatemi ad imparare il C++ :)) (linguaggio che comunque
: presto studiero'... piu' linguaggi so piu' mi diverto)
Puoi provare a vedere qualche libreria, tipo ncurses.
Ciao ciao
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

domanda che viene dopo... cosa devo fare?la cos che mi e' sembrata molto
  Forse puoi provare a leggere tutta la stringa e poi considerare solo il
primo carattere... no?
  Ciao.

setbuf(3)                                                           setbuf(3)
Si, ma non serve a niente per il problema di Stefano -- che stdin
sia bufferizzato o meno, ha comunque la specifica di ritornare
_tutti_ i caratteri letti da stdin, non solo il primo di ogni riga, come
pare volere Stefano.  Anche C++, di per se`, non aiuta piu` di
tanto, se ho ben indovinato la speranza di Stefano: lui vorrebbe
(sbaglio?) leggere caratteri gia` presenti, ma SENZA piantarsi
in attesa di caratteri non ancora immessi, giusto?
Se si vuole semplicemente il primo carattere di una riga,
ignorando tutti gli altri, la cosa piu` semplice e` fare fgets
in C, o getline in C++, esaminando poi solo il primo dei
caratteri cosi` ottenuti.
Per cose come: leggere un carattere non appena digitato
senza dover attendere un return, sapere se l'utente ha gia`
digitato dei caratteri senza fermarsi in attesa, ecc ecc, ne`
C ne` C++ _standard_ offrono alcuna soluzione.  Si puo`,
e si deve, ricorrere a funzioni non portatili, dipendenti dal
sistema operativo in gioco ecc ecc.
Alex

 in attesa di caratteri non ancora immessi, giusto?
non proprio...il mio caso e' il seguente:
io ho una domanda del tipo:
vuoi immettere il nome del file (s/n)
a cui, in caso di risposta affermativa, (seguita da invio... non
pretendo di attendere il singolo carattere s o n e, senza invio,
proseguire nella elaborazione...troppo complesso per ora :) ) segue:
immetti il nome del file:
ora... se un debugger (leggi "un bravo pirla") alla domanda 1 mi scrive
sgdsnjfngjdfn jisfhsdumhf
ovviamente... un getchar mi rileva il primo carattere 's' ... e quindi
passa alla domanda successiva...
le rimanenti porcherie mi restano come coda nella successiva domanda, che
oltretutto viene lanciata automaticamente in quanto alla fine della
stringa stessa c'e' lo \n di invio...
non posso usare uno scanf perche' uno spazio mi fregherebbe, a meno di
utilizzare strani cookie di formattazione... nemmeno un fgets con un
buflen di uno ... perche' tanto quello che prende su lo prende su...
quello che invece non prende su rimane nella coda di input e ricado nello
stesso problema... 
l'unica idea che mi viene e' fare un getchar ricorsivo fino ad arrivare a
\n ed esaurire il buffer , cosi' al presentarsi della nuova domanda e del
nuovo input (fatto con il malloc e l'eventuale realloc come gia' alex in
un post precedente mi consigliava) ho uno stdin vuoto... ma mi sembra
abbastanza 'stupida' come soluzione... 
frugando nel man della funzione fflush di un mio amico ho comunque trovato
una funzione chiamata fpurge... lui ha una slackware 3.4, io una 3.5 ...ma
non so se ha aggiornato le librerie...sul mio sistema linux infatti non
c'e'...forse devo aggiornare le libc? ho le libc-5.4.44 insomma... le
libc5 :)
boh... ad ogni modo mi pare che il thread sia coinvolgente... e penso che
puntera' a diventare un 'imparare le ncurses (was: Re: Beh... allora
chiediamola tutta... (gets e malloc) )' ... voi che dite? (a proposito..
esiste un buon manualetto d'uso dele ncurses? non ho voglia di stamparmi
una per una le pagine di manuale delle varie funzioni...)
PS: per 'evoluto' intendo 'provato'... il C e' un linguaggio in voga da
parecchi anni (sicuramente almeno 30 :) ) ...
---------------------------
quela:~# mount -t vfat /dev/hda1 /windows
mount: error mounting /dev/hda1... mmmh...It's full of rubbish !!
Try this instead:     mke2fs -c /dev/hda1 <block size>
It will work better !
---------------------------
ICQ # 20612221 
                                          Stefano Borini

buflen di uno ... perche' tanto quello che prende su lo prende su...
E allora fai, come gia` suggerito piu` volte, un fgets con un buffer
di 1000 e guarda solo il 1o carattere, il 1o non-bianco, o cose del
genere...
Alex

buflen di uno ... perche' tanto quello che prende su lo prende su...


 mi fa il getchar e mi prende il s
Per controllare l'i/o interattivo a terminale la cosa migliore e' la
libreria ncurses (man ncurses). In alternativa puoi disabilitare la
bufferizzazione e cosi' controllare carattere per carattere quello che
batte l'utente sulla tastiera. Ecco un esempio:
#include <stdio.h>
#include <termio.h>
int main()
{
   struct termio cooked, raw;
   int key;
   /* Elimina la bufferizzazione del terminale: */
   ioctl(0, TCGETA, &cooked);
   memcpy(&raw, &cooked, sizeof(struct termio));
   raw.c_lflag &=~ (ICANON | ECHO);
   raw.c_cc[VEOL] = 1;
   raw.c_cc[VEOF] = 2;
   ioctl(0, TCSETA, &raw);
   /* Mostra i codici dei tasti premuti: */
   while( (key=getchar()) >= 0 )  printf("%c[%d] ", key, key);
   /* Ripristina la bufferizzazione del terminale: */
   ioctl(0, TCSETA, &cooked);
   return 0;
}
Ciao,
- Salsi

La funzione getch() legge il carattere digitato senza attendere l'invio.
  La funzione getch() non e' standard, credo. Almeno, nel gcc del linux che
ho io non c'e' e se vuoi controllare la tty senza aspettare che il carattere
venga premuto devi fare salti non dico mortali, ma neanche saltelli sul
posto :)
Tutta la roba tipo getch(), kbhit() e -piu' in generale- la roba definita
nel conio.h dal Turbo C 3.0 in su e' ok se devi rilasciare solo l'EXE, ma se
vuoi fare qualcosa di portabile no. :((
  Ciao,
  Mabu.

parecchi anni (sicuramente almeno 30 :) ) ...
No, assai meno di 30.  Trent'anni fa c'erano, abbastanza
diffusi, Fortran, Cobol, LISP, Algol, ciascuno in un certo
numero di "dialetti"; meno diffusi, ma pur sempre di una
certa importanza, PL/I, RPG, APL, BCPL, ecc ecc.  Il
linguaggio C fu sviluppato da Thomson e Ritchie, al
Computer Research Lab dei Bell Labs (allora AT&T),
come parte dello sviluppo del nuovo sistema operativo
Unix, nei primi anni '70; ispirato sostanzialmente al
BCPL (attraverso un linguaggio intermedio, B, che non
usci` mai dal CRL, e di cui si sono perse le tracce),
con la sostanziale aggiunta dei "tipi" (BCPL e B sono
sostanzialmente "type-less") e vari costrutti ispirati ai
vari linguaggi suddetti (ad esempio, la sintassi dei
commenti e` quella del PL/I) e ad altri emersi nel
frattempo (come ad esempio Algol 68, che nonostante
il nome non era un dialetto di Algol, ma in realta` un
linguaggio molto piu` ricco e complesso, con molte
e profonde differenze).
Alex