Newsgroup: it.comp.lang.c
Titolo: programma caratteri non funzionante. help please!

Ciao,
Ho elaborato questo programmino
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int l, i;
    char v[101];
    printf("Inserire la lunghezza della stringa che si intende
inserire:\n");
    scanf("%d", &l);
    v[l] = '\0';
    for (i = 0; i < l; i++)
    {
        printf("Inserire la %d-esima lettera:\n", i);
        scanf("%c", &v[i]);
    }
   system("PAUSE");
    return 0;
}
Non mi so capacitare perché il programma exe debba dare questo
bruttissimo output:
Inserire la lunghezza della stringa che si intende inserire:
5
Inserire la 0-esima lettera:
Inserire la 1-esima lettera:
Mi spiego meglio: perché mai il programma mi spara
Inserire la 0-esima lettera:
Inserire la 1-esima lettera:
una di seguito all'altra senza aspettare dopo
Inserire la 0-esima lettera:
che l'utente immetta una lettera?
Grazie

 che l'utente immetta una lettera?
Perche' l'interazione con il terminale non è un aspetto standard del C. 
Dipende dalla piattaforma e dal compilatore e non è mai una buona idea 
scrivere codice non portabile.
Il modo corretto di acquisire dati dall'esterno è leggerli da un file, 
il fatto che stdin sia attaccato per default ad una finestra di 
terminale è solo un caso specifico.
Per il C esiste solo questo modello:
         input
           |
           | stdin
           V
        PROGRAMMA
          |   |
   stdout |   | stderr
          V   V
     output   errori
Mi domando: chi insenga il C facendo fare questi esercizi con getchar e 
scanf etc, ha mai fatto un vero programma C in vita sua?
Remo.D

 Remo.D
Non mi è molto chiara la tua risposta,
ad ogni modo non funziona nemmeno questo programma:
#include <stdio.h>
#include <stdlib.h>
int main()
{
    char c1, c2, c3;
    printf("Insert the first letter:\n");
    scanf("%c", &c1);
    printf("Insert the second letter:\n");
    scanf("%c", &c2);
    printf("Insert the third letter:\n");
    scanf("%c", &c2);


Perche' l'interazione con il terminale non č un aspetto standard del C. 
Nell'esempio di andrew si sta facendo uso di funzioni standard e
portabili. Le funzioni scanf() e getchar() sono perfettamente
portabili, ma bisogna conoscere il loro funzionamento. Per me
andrebbero evitate del tutto a beneficio di fgets().
Nell'esempio di andrew, il problema č che la funzione scanf() accetta
l'input e lo memorizza nella variabile, ma lascia nel buffer il
new-line, che viene letto dalla scanf() successiva, che quindi lascia
vuoto il buffer. La terza scanf(), trovando il buffer vuoto, torna a
chiedere l'input all'utente. E' per questo che sembra ci sia un salto.
Una delle soluzioni, se proprio si vuol usare scanf(), č svuotare il
buffer di tastiera con un:
while (getchar() != '\n') 
   ;
Tra una scanf() e l'altra.

}
#include <stdio.h>
#include <stdlib.h>
void flushKeyBuff() {
    while (getchar() != '\n')
       ;
}
int main()
{
    char c1, c2, c3;
    printf("Insert the first letter:\n");
    scanf("%c", &c1);
    flushKeyBuff();
    printf("Insert the second letter:\n");
    scanf("%c", &c2);
    flushKeyBuff();
    printf("Insert the third letter:\n");
    scanf("%c", &c2);
    flushKeyBuff();
    return 0;
}

 Una delle soluzioni, se proprio si vuol usare scanf(), è svuotare il


il buffer dovrebbe riempirsi con il solo carattere x, non ti pare?
No e l'ho spiegato nel messaggio. L'input in C è line-buffered, quindi
il buffer si riempie fino all'invio del new-line e la sequenza di
new-line stessa rimane nel buffer.

 new-line stessa rimane nel buffer.
per sequenza di newline intendi l'utente che digita enter?
Poi, nella tua funzione ad hoc,
void flushKeyBuff(void)
{
    while (getchar() != '\n');
}
il ciclo while viene eseguito fintanto che ... non capisco...

il ciclo while viene eseguito fintanto che ... non capisco...
Fintanto che non viene letto il new-line...

 Fintanto che non viene letto il new-line...
Ciao,
Secondo me questa soluzione è ancora più semplice. Che ne dici?
#include <stdio.h>
#include <stdlib.h>
int main()
{
    char c1, c2, c3;
    printf("Insert the first char immagazzinato poi in c1:\n");
      /* l'utente digita un carattere da tastiera e quindi digita
enter.
         In totale ha quindi digitato due caratteri, il secondo dei
quali è newline
         ossia il carattere '\n' che equivale al carattere ASCII 0A
esadecimale.
         Nel buffer di tastiera sono quindi presenti due caratteri.
      */
    scanf("%c", &c1);
     /* Questa scanf legge il primo carattere digitato da tastiera e
lo memorizza
        nella variabile c1
        (scanf legge dal buffer di tastiera ed elimina dal buffer ciò
che legge, il
        buffer di tastiera è FIFO),
        ma lascia nel buffer di tastiera il carattere newline
     */
    getchar();  /* getchar è una fz della libreria stio
                   che legge un carattere da tastiera
                   i.e., legge dal buffer di tastiera.
                */
    // adesso il buffer di tastiera è vuoto
    printf("Insert the second char immagazzinato poi in c2:\n");
    scanf("%c", &c2);
    getchar();
    printf("Insert the third char immagazzinato poi in c3:\n");
    scanf("%c", &c3);
    getchar();


                */
Se ti ho scritto quella funzione, con un "while", c'è un motivo, non
credi? Sostituisce il ciclo con un singolo getchar() come hai fatto
nel codice iniziale che chiedeva tre caratteri, poi, alla prima
scanf(), prova a dare in pasto "topolino" e vedi che succede.

Sostituisce 
SostituiscI

 scanf(), prova a dare in pasto "topolino" e vedi che succede.
Con la tua soluzione, anche se alla prima richiesta di inserimento del
carattere (la prima scanf) inserisco 4 caratteri, gli ultimi tre
inseriti vengono eliminati dal buffer di tastiera.
Quindi anche la mia soluzine mi sembra corretta... A patto che
l'utente inserisca un singolo carattere ogni volta che gli viene
richiesto.
Non mi sembra di sbagliare....

Quindi anche la mia soluzine mi sembra corretta...
No, la tua soluzione non è corretta, perché rende troppo fragile
l'input. Non capisco perché a fronte di due soluzioni, una sicura e
corretta e l'altra non sicura e quindi scorretta tu prediliga la
seconda.

> portabili, ma bisogna conoscere il loro funzionamento.
La semantica di scanf() stabilisce che se non ci sono abbastanza 
caratteri nel file di input per fare il match, la funzione ritorna. Idem 
per getc().
Quello che non è standard è il fatto che su Windows, compilando con 
alcuni compilatori, se stdin è collegato ad un terminale e non ci sono 
caratteri nel buffer, la scanf() si fermi ad aspettare l'input dell'utente.
Non c'e' nessuna garanzia che questo avvenga in altri ambienti o con 
altri compilatori.
Remo D.

 Non mi è molto chiara la tua risposta,
Il C definisce un modello di I/O molto semplice. Ci sono stream a cui si 
puo' accedere tramite puntatori ad una struttura FILE. Ogni stream puo' 
essere aperto in modalità text o binary e puo' essere "fully buffered" 
(i dati vengono trasmessi quando il buffer è pieno), "line buffered" (i 
dati vengono trasmessi quando nel buffer appare il caratter 
"end-of-line") o "unbuffered" (i dati vengono trasmessi subito).
Ci sono tre stream di tipo text che vengo aperti ogni volta che un 
programma viene lanciato:
   stdin   per l'input (scanf, getchar, gets, ...)
   stdout  per loutput (printf, ...)
   stderr  per gli errori (da usare con fprintf etc)
stderr viene aperto come unbuffered. stdout e stdin come fully buffered 
se e solo se è possibile determinare che il device a cui sono collegati 
non è un interattivo. Da notare che lo standard non stabilisce se 
debbano essere aperti come "unbuffered" o come "line buffered" in questo 
caso.
Il C non sa nulla di cosa sia un terminale o cosa voglia dire "aspettare 
un carattere da tastiera". Solo gli stream sono definiti, tutto il resto 
dipende dalla piattaforma e dal compilatore.
Il comportamento "piu' diffuso" è che stdin sia aperto in modalità "line 
buffered" quando è collegato ad una console. Inoltre, benche' non sia 
richiesto dal C, le funzioni di input come la scanf e la getc sospendono 
l'esecuzione del programma se il file è buffered ed il buffer è vuoto.
Immagina la scena.
Il compilatore ha deciso che quando stdin è attaccato ad un terminale 
viene aperto come "line buffered".
Il buffer è vuoto, la scanf() viene eseguita e, visto che il compilatore 
ha deciso di implementarla in modo sincrono, il programma si ferma.
Nel frattempo dalla tastiera arrivano i caratteri che vengono inseriti 
nel buffer di input fino a che non batti invio.
A quel punto è comparso il carattere di "end-of-line" (\n) ed il buffer 
viene trasmesso al programma che sta aspettando sulla scanf().
Se hai in mente la scena descritta, la spiegazione di Andrea dovrebbe 
esserti chiara.
Quello che sostengo io, e se dovessi aver torto fatemelo sapere, è che 
questo comportamento non è portabile perche' non è garantito dallo 
standard. stdin potrebbe essere "unbuffered" oppure la scanf() potrebbe 
ritornare immediatamente interpretando un buffer vuoto come end-of-file.
Se proprio si deve interagire con il terminale, meglio lasciar stare 
scanf(), getc() etc ed usare apposite librerie. Si ottiene anche un 
controllo maggiore sul dialogo con l'utente.
Remo.D

 richiesto. [zap]
IMHO Mai fidarsi dell'utente.
Enrico

standard.
Non capisco che cosa intendi. La funzione scanf() è standard quindi il
suo comportamento è avallato dallo standard.

caratteri nel buffer, la scanf() si fermi ad aspettare l'input dell'utente.
Ma che stai dicendo? non č affatto cosě. La funzione scanf() serve
PROPRIO ad implementare questo comportamento.

 PROPRIO ad implementare questo comportamento.
Io non l'ho trovato nello standard. Puoi indicarmi il paragrafo?
Nello standard, scanf(...) è definita (7.19.6.4) come fscanf(stdin, ...) 
e nella definizione di fscanf (7.19.6.2) non c'e' scritto che se il 
buffer è vuoto l'esecuzione si arresta.
Naturalmente potrebbe essere in qualche altro paragrafo dello standard 
ma io non ho trovato niente.
Remo.D.

Andrea Laforgia ha scritto:

C'e' anche il problema di come è aperto stdin. Come ho scritto prima lo 
standard non stabilisce come debba essere aperto quando è attaccato ad 
un terminale. Se dovessere essere aperto come "unbuffered" la scanf 
dovrebbe riprendere subito con un solo carattere come input (senza 
aspettare il '\n'). Non credi?
Remo.D

Remo D. ha scritto:

P.S. Per essere sicuro sono andato a rileggermelo tutto. Nel paragrafo 9 
  e' scritto esplicitmente:
[...] If the length of the input item is zero, the execution of the 
directive fails; this condition is a matching failure unless 
end-of-file, an encoding error, or a read error prevented input from the 
stream, in which case it is an input failure. [...]

un terminale.
Niente affatto. Quando stdin è associato a un input interattivo, la
modalità è line-buffered e questo vale sia sotto Windows che sotto
Linux, che sotto qualsiasi Unix.

buffer è vuoto l'esecuzione si arresta.
Chi ha detto che l'esecuzione si arresta? non ho mai detto una cosa
del genere. L'esecuzione non si arresta affatto, tanto è vero che
l'input viene richiesto all'utente, se a stdin è associato ad un
dispositivo interattivo. Guardare all'attesa dell'input dall'utente
come un "arresto" del funzionamento della funzione è assolutamente
sbagliato.

Andrea Laforgia ha scritto:

Hai ragione, non parliamo di arresto del programma. Comunque mi puoi 
dire dove è indicato che la scanf() debbe attendere l'input dell'utente?
Da qui' non sembrerebbe nota "the unavailability of input characters":
7.19.6.2 (4)
The fscanf function executes each directive of the format in turn. If a 
directive fails, as detailed below, the function returns. Failures are 
described as input failures (due to the occurrence of an encoding error 
or the unavailability of input characters), or matching failures (due to 
inappropriate input).
 > Niente affatto. Quando stdin è associato a un input interattivo, la
 > modalità è line-buffered e questo vale sia sotto Windows che sotto
 > Linux, che sotto qualsiasi Unix.
Questo è quello che dice lo standard:
7.19.3 (7)
At program startup, three text streams are predefined and need not be 
opened explicitly — standard input (for reading conventional input), 
standard output (for writing conventional output), and standard error 
(for writing diagnostic output). As initially opened, the standard error 
stream is not fully buffered; the standard input and standard output 
streams are fully buffered if and only if the stream can be determined 
not to refer to an interactive device.
Dove è scritto che stdin viene aperto come line-buffered?
Per essere chiari, so benissimo che sotto Windows e Unix il 
comportamento della scanf() è quello che hai descritto tu sto solo 
dicendo che non lo trovo da nessuna parte nello standard C e, quindi, 
dipende dalla piattaforma/compilatore che si usa.
Remo.D

comportamento della scanf() è quello che hai descritto tu
Se lo sai, allora, con tutto il rispetto, la tua risposta iniziale ad
andrew è data in malafede. Se lo sai, sai benissimo che il problema di
andrew è dovuto all'input line-buffered.

 andrew è dovuto all'input line-buffered.
No, il problema di andrew è fare assunzioni ingiustificate sul 
comportamento di scanf() e volerla usare per interagire con il terminale.
Il comportamento di scanf() che hai descritto è ragionevole e molto 
diffuso ma si basa su come è implementato il dialogo con il terminale, 
non sulla semantica di scanf().
Personalmente ritengo che sia una pessima pratica usare le funzioni di 
stream per interagire con un terminale interattivo, ci sono rimasto 
scottato e cerco di scoraggiarne l'uso quando posso (come in questo 
caso). Soprattutto con chi sta imparando.

 Perché l'input non puň essere unbuffered, per ovvie ragioni. 
Non vedo ragioni perché DEBBA essere buffered. Anzi vedo delle buone 
ragioni perché POSSA essere unbuffered. Immagino anzi che alcuni 
terminali implementino l'input unbuffered.
E.

 terminale? E' di questo che stiamo parlando.
Che l'input venga "aspettato" č ovvio, non č mica che pretendi che 
l'utente possa scrivere milioni di caratteri al secondo? Cioč se 
l'utente non preme nessun tasto la scanf DEVE rimanere in attesa. Questo 
mi pare č insito nel concetto di stream. Il punto č se l'input č 
bufferizzato o meno, cioč se l'attesa termina al primo carattere oppure 
al newline.
E.

 l'utente possa scrivere milioni di caratteri al secondo? 
Naturalmente no, pero' posso immaginare una situazione in cui la scanf() 
non trovando niente nel buffer fallisca ritornando 0.
Probabilmente con stty è possibile settare un terminale perche' si 
comporti in questo modo, non ne sono certo.
Remo.D

stream per interagire con un terminale interattivo
Ma per favore!

Il punto č se l'input č bufferizzato o meno
Il punto NON č questo: a prescindere che l'input sia bufferizzato o
meno (il buffering non c'entra in tutto questo), se stdin č legato a
un dispositivo specifico, č ovvio che sia quel dispositivo specifico
ad essere usato per l'input. Qui si sta insistendo sul fatto che
scanf() non debba essere usata per l'input da tastiera? č una
sciocchezza bella e buona.

non trovando niente nel buffer fallisca ritornando 0.
Non è un comportamento accettabile, perché vorrebbe dire che non
potresti mai usare scanf() per l'input da tastiera, visto che la prima
volta che la chiami, il buffer è evidentemente vuoto.
Non ti offendere, ma se stai insistendo sul fatto che scanf() non
possa essere usata per l'input da tastiera, stai dicendo una
sciocchezza.

 sciocchezza.
Andrea, non mi offendo di certo pero' se rileggi i post precedenti 
noterai che ho solo detto che non c'e' nessuna garanzia che usare 
scanf() per leggere da tastiera produca il risultato atteso.
Ho anche detto che la soluzione che hai indicato tu è perfettamente 
corretta sotto le ipotesi che scanf() aspetta se stdin è collegato ad un 
terminale ed il buffer è vuoto e stdin è line-buffered. Ipotesi 
largamente verificate dagli ambienti piu' diffusi ma non necessariamente 
da tutti gli ambienti.
Se poi mi indichi dove sta scritto che il comportamento di scanf() che 
hai descritto è garantito in ogni caso, allora ho detto una sciocchezza 
ed ho anche imparato qualcosa di nuovo.
Remo.D.

hai descritto è garantito in ogni caso
Te l'ho già spiegato, ma non leggi. C'è bisogno che qualcuno ti SCRIVA
che se un dispositivo di input è interattivo e si richiede dell'input,
quell'input debba essere inserito da un utente?

 Te l'ho già spiegato, ma non leggi. 
Ti assicuro che ho letto con attenzione quello che hai scritto, pero' 
non ho visto nessun riferimento allo standard o ad altre fonti che 
sostengano la tua tesi.
A sostegno della mia tesi ho portato i paragrafi dello standard che 
descrivono fscanf ed il comportamento di stdin ed ora un esempio 
concreto di un programma che usa scanf per leggere da un terminale e si 
comporta in modo diverso a seconda della natura del terminale stesso.
A scanso di equivoci ribadisco la mia tesi:
"Leggere dati da un terminale con scanf() non offre nessuna garanzia sul 
risultato perche' dipende dalle caratteristiche del terminale stesso e 
non dalla semantica di scanf() (e quindi dipende dal sistema operativo, 
dalla libreria di runtime del compilatore e dall'hardware sottostante). 
Per questo motivo è meglio evitarlo e passare i dati attreverso file 
(incluso stdin) o su linea di comando".
Remo.D

 PROPRIO ad implementare questo comportamento.
Non sono sicuro che risolvi i dubbi ma:
Da 
http://www.opengroup.org/onlinepubs/009695399/functions/
xsh_chap02_05.html#tag_02_05
When a stream is ``unbuffered'', bytes are intended to appear from the 
source or at the destination as soon as possible; otherwise, bytes may be 
accumulated and transmitted as a block. When a stream is ``fully 
buffered'', bytes are intended to be transmitted as a block when a buffer 
is filled. When a stream is ``line buffered'', bytes are intended to be 
transmitted as a block when a newline byte is encountered. Furthermore, 
bytes are intended to be transmitted as a block when a buffer is filled, 
when input is requested on an unbuffered stream, or when input is 
requested on a line-buffered stream that requires the transmission of 
bytes. Support for these characteristics is implementation-defined, and 
may be affected via setbuf() and setvbuf().
In pratica, nello standard C, l'interazione con un dispositivo di IO è 
implementation defined.
In questo caso, lo standard di riferimento è POSIX.
Manlio Perillo

 natura della scanf() stessa.
Comunque c'č anche freopen (standard). L'assunzione che stdin debba
essere legata ad un terminale di input č IMHO ingiustificata. 
A margine preferisco funzioni di input piů robuste: prendo con fgets (o
analoghe), analizzo l'input e faccio quello che devo fare.
-- 
-riko

 secondo il tuo parere, non dovrebbe accadere, giusto?
A mio avviso il programma fa in entrambi i casi quello che gli è stato 
chiesto. E' il terminale che si comporta diversamente.
E.

 sciocchezza bella e buona.
Su questo sono d'accordo.
E.

 Su questo sono d'accordo.
Il punto č che, se la mia tesi č corretta, leggere dalla tastiera con 
scanf() non produce risultati affidabili perche' il comportamento di 
scanf() dipende dal terminale. Quindi, in generale, non si dovrebbe usare.
Se, invece, mi sono sbagliato, allora č una sciocchezza. Pero' vorrei 
essere confutato prima di essere accusato di dire sciocchezze!
R.D

 scanf() dipende dal terminale. Quindi, in generale, non si dovrebbe usare.
Io potrei anche farmi un terminale che mi scambia le lettere x ed y 
dall'input dell'utente (o piů brutalmente potrei scambiare i tasti x e y 
sulla tastiera). Allora nessun programma sarebbe in grado di gestire 
correttamente l'input dell'utente.
E.

?manu* ha scritto:

Non mi sembra sia la stessa cosa, non stiamo parlando di cosa viene 
letto ma di come funziona la scanf(). Il punto in discussione č:
"Il linguaggio C garantisce che la funzione scanf() aspetti l'input 
dell'utente se stdin č un terminale?"
La mia risposta č "no" perche' da nessuna parte č scritto che la 
funzione scanf() si comporta in questo modo. La definizione del 
linguaggio C lascia questo dettaglio all'implementazione.
Per me questo basta per sconsigliarne l'utilizzo come metodo per 
acquisire dati da un terminale.
R.D.

 dell'utente se stdin è un terminale?"
La funzione scanf aspetta l'input dallo stream stdin. Il comportamento 
di scanf dipende solo da quello che arriva attraverso lo stream, non da 
quello che c'è collegato dall'altra parte. Questo vale per tutte le 
funzioni della libreria standard.
E.

 La funzione scanf aspetta l'input dallo stream stdin.
Perfetto, almeno abbiamo trovato il punto su cui non ci troviamo.
L'ho scritto già su altri post e lo scrivo un'ultima volta, poi ognuno è 
libero di credere quello che vuole.
La scanf() non ha l'obbligo di aspettare i dati da stdin se questi non 
sono disponibili.
Per essere piu' chiari nessuno garantisce che in questo pezzo di codice
   ...
   printf("Inserisci un valore :");
   scanf("%d",&x);
   ...
al momento della scanf all'utente verrà data la possibilità di inserire 
il valore. La scanf() potrebbe lecitamente ritornare perche' interpreta 
il buffer vuoto di stdin come un end-of-file.
Ripeto: aspettare l'input da stdin e' il caso piu' comune quando stdin è 
attaccato ad una finestra di terminale ma non c'e' nessuna garanzia che 
debba essere SEMPRE cosi'.
Il motivo di questo comportamento è nella definizione stessa di scanf() 
(7.19.6.2) e nel modo in cui è definito stdin (7.19.3).
Lo standard C è sulla rete ed ognuno se lo puo' leggere se vuole: 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1336.pdf
Non capisco perche' gli unici argomenti contro la mia tesi sono che "e' 
ovvio", "deve essere cosi'", "sono sciocchezze" etc.
Se avete delle prove che la scanf debba NECESSARIAMENTE e SEMPRE 
aspettare l'input da stdin, per favore argomentate seriamente.
R.D

 debba essere SEMPRE cosi'.
scanf aspetta sempre l'input da stdin. Nei casi che tu hai riportato e' 
il terminale che non "alimenta" lo stream e quindi su stdin non arriva 
niente.
E.

 scanf aspetta sempre l'input da stdin.
No. Se fai un freopen che ricollega stdin ad un file, cosa perfettamente
lecita, automaticamente non aspetta più (e giustamente!).
-- 
-riko

 niente.
Nient'affatto. Con "stty -icanon min 0" il terminale manda i dati 
correttamente se questi sono disponibili, se non sono disponibili manda 
un eof. In quesl teminale, tutti gli altri programmi funzionano 
perfettamente perche' se devono leggere da tastiera lo fanno con i mezzi 
piu' appropriati usando termio o altre librerie specifiche.
Questo dimostra che scanf() NON aspetta SEMPRE l'input da stdin. Se 
cosi' fosse sarebbe stata implementata in modo da essere insensibile 
rispetto alla configurazione del terminale.
Ad esempio nel vecchio BASIC era garantito che la INPUT dovesse 
aspettare i dati inseriti dall'utente. Non c'era niente che tu potessi 
fare perche' questa era la semantica della INPUT e non dipendeva dal 
terminale in cui il programma veniva eseguito ma dalla definizione 
stessa del linguaggio.
Io continuo a dire che il fatto che scanf() debba aspettare i dati 
dell'utente NON è stabilito dalla definizione dal linguaggio C. Se c'e' 
un punto nella definizione del linguaggio in cui si dice il contrario 
sono ben lieto di aver imparato qualcosa di nuovo.
R.D

 essere confutato prima di essere accusato di dire sciocchezze!
Invece hai perfettamente ragione, sulla scanf() il comportamento e' 
implementation
dependent.
Infatti puo' tranquillamente non essere sospensiva ;-)
Questo lo si puo' realizzare con alcuni sistemi real-time (posix/QNX/ 
vxWorks etc.)
dove e' possibile impostare il funzionamento desiderato e rendere non 
sospensiva la
scanf [e altre simili, anche se il comportamento sospensivo e' 
normalmente il default].
Con QNX, per esempio, basta impostare lo stdin come non bloccante con la
chiamata seguente:
    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
..e tutto quello legato a stdin (tastiera linea seriale o quant'altro) 
diventa *non*
bloccante...ovviamente poi occorre necessariemante testare il ritorno 
della funzione
e l' errno associato (con vxWorks idem) e accollarsi la relativa gestione.
Questo comportamento puo' servire (e serve!) per gestire situazioni 
particolari,
come ad esempio implementare timeout su operazioni dell' utente che 
*devono*
essere eseguite in un determinato intervallo di tempo.
Con Win e Lnx invece la scanf() e' sospensiva, anche se con l' Linux
hai la possibilita' di personalizzarla, visto che i sorgenti sono 
disponibili ;-)
Ciao
B.

 piu' appropriati usando termio o altre librerie specifiche.
Qui però esageri. Non è che siccome la semantica rispetto al terminale
non è definita *non* usi funzioni di input standard.
Non è la prassi comportarsi in questo modo.
scanf è una funzione sconsigliata spesso e volentieri per una serie di
buoni motivi (spesso legati alla sicurezza), per un'altra classe di
buoni motivi (se bisogna prendere input non banale trovo la logica di
gestire gli errori "parziali" più complessa in scanf rispetto che
prendere l'input e prendermi io i vari pezzi). 
Ma di qui a dire che per fare un po' di I/O si usano le librerie
dipendenti dal sistema ce ne passa. 
-- 
-riko

 disponibili ;-)
Direi che non č necessario. Non ho sotto mano un Linux sui due piedi, ma
con OS X se chiami
    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
hai esattamente il comportamento che hai descritto. Siccome fcntl č una
funzione standard[0], IIRC, e pure O_NONBLOCK lo č, mi aspetto che
funzioni ugualmente anche su Linux.
-----
[0] in questo caso standard POSIX, non standard C90/C99.
-- 
-riko

 stessa del linguaggio.
Di quale BASIC stai parlando? Se il tuo programma BASIC gira su un 
terminale, allora modificando il terminale certamente puoi farlo 
impazzire. Un linguaggio ti dà le garanzie su quello su cui può darle. 
Passando al limite, se sulla mia tastiera scambio fisicamente i tasti X 
e Y nessun programma sarà in grado di capire che li ho scambiati.
E.

 e Y nessun programma sarà in grado di capire che li ho scambiati.
Come ho detto prima, questo esempio non e' calzanta perche' non stiamo 
ragionando su cosa arriva alla scanf() ma sul modo in cui 
presumibilmente funziona la sua interazione con un termnale.
Comunque penso che chiunque abbia interesse a questo argomento ormai 
avrà tutti i riferimenti per farsene un idea per conto proprio. Gli 
altri si saranno abbastanza rotti per cui mi arrendo, ciascuno si regoli 
come meglio crede (ma prima leggetevi la definizione del linguaggio).
R.D.

 e Y nessun programma sarà in grado di capire che li ho scambiati.
Esempi non pertinenti.  Il BASIC prima di aprire il terminale per 
aspettare l'input lo settava correttamente.  Le funzioni definite dal 
C non prevedono questo, ma lasciano questo compito all'interpretazione 
del compilatore.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

 dependent.
Quello che riporti in seguito non riguarda in particolare la scanf, ma 
si applica ugualmente a getchar o fgets o altro...
Dunque non ha senso sconsigliare l'uso della scanf per quel motivo. Ce 
ne son ben altri per cui farlo.
E.


Infatti non sconsiglio niente! forse ho capito male, ma sembrava che si
affermasse che il comportamendo di scanf fosse bloccante, cosa che
invece non e'.
Ciao,
B.

brix99luftballons ha scritto:

Ero io lo "sconsigliatore".
Io sconsiglio di utilizzare la scanf() per implementare dialogi 
interattivi con l'utente del tipo:
   "Inserisci un valore : _"
o
   "Premi un tasto per continuare."
Remo D.