Newsgroup: it.comp.lang.c++
Titolo: Il C++ e' impazzito!

Salve. Possiedo il Visual C++ 6.0.
Non mi ha dato mai problemi.
Adesso inserendo questo
semplicissimo codice (che viene compilato
senza alcun problema) sapete che succede?
Mi salta l'ultima scanf (quella del carattere)!!!!!
Perche'?????
E' forse impazzito il mio PC o cos'altro???
Questo e' il codice:
#include <stdio.h>
int main ();
main()
{ 
  char parola[10];
  char carattere;
  int x,y;
  printf ("\nInserire la parola: ");
  scanf("%s", parola);
 
  printf ("\nInserire la coordinata x: ");
  scanf ("%d", &x);
 
  printf ("\nInserire la coordinata y: ");
  scanf ("%d", &y);
 
  printf ("\nVerticale od Orizzontale? ");
  scanf ("%c", &carattere);
   return 0;
}
P.S.: gli altri codici che compilo funzionano alla perfezione.

 
-- 
"a` parte isso, tenho em mim
 todos os sonhos do mundo"

>Stampa il valore di carattere e lo scoprirai.
L'ho fatto, e il bello e' che non me lo stampa!!!!
ho scritto
printf("%c",carattere);
e non mi stampa nulla!!!!
Ma che sta succedendo????

 
Proprio nulla? Sicuro? 
Prova questo:
 printf("---->%c<----",carattere);
;-)
Max

 printf("---->%c<----",carattere);
Mi ritorna a capo.
Ma perche'???
Io prima gli faccio tanto di scanf!!!!
E lui però mi salta l'istruzione. Per quale motivo????
Mi potresti gentilmente spiegare che sta succedendo?
Senno' questo benedetto esame di informaticaI non lo riesco a dare.
E di esercizi ne devo scrivere ancora tanti.
Grazie a chi vorra' rispondermi.
©Scaccomatto

  scanf ("%c", &carattere);
scanf ("\n%c", &carattere);
Luc.

 
Scusa la curiosità: sono esercizi in C o in C++?
In C++, l'uso di printf() e compagnia è fortemente "scoraggiato" giacchè
questo linguaggio dispone di meccanismi più versatili e type-safe per
gestire l'output. Se si tratta di C, forse è più appropriato che posti i
tuoi quesiti su it.comp.lang.c.
Max

 wrote in message
Pine.LNX.4.10.100060...@c64.comm2000.it...
Intanto ti ringrazio.
Comunque ho postato qui perche' sto usando il MS Visual C++ 6.0.
Ciao
©Scaccomatto

 Ma perche'???
Perchè nel tuo buffer di input c'è un carattere non processato dall'istruzione scanf precedente il CR.
Facciamo chiarezza ;)
 printf ("\nInserire la coordinata y: ");
 scanf ("%d", &y);
Per poter "inviare" l'input alla scanf devi premere return (CR)
ma quello che la funzione scanf deve processare è un intero,
il primo carattere che non rispetta questa sintassi viene ignorato
_e_ lasciato nel buffer di input.
Quindi se premi '1', '2','\n' la scanf() legge 12 e lascia il CR nel buffer di input
pronto per essere letto dalla scanf() successiva che vuole un solo carattere (qualsiasi).
Tenendo il programma nell'ultima versione, prova a scrivere
------------
Inserire la coordinata y: 10w
Verticale od Orizzontale?---->w<----
------------
hai visto la w ?
10 è un intero, 'w'non fa parte del numero e viene ignorato dalla scanf,
resta nel buffer di input, preso dalla scanf del carattere
Soluzione ?
- in C (giusto per un esame 8-))
   Svuota il buffer di input prima di effettuare la scanf del carattere mediante la funzione
   fflush( stdin ); /* svuota il buffer dello standard input */
- in C++ (meglio, molto meglio !)
    utilizza cin
    risparmi tempo, fatica e un mucchio di "idiosincrasie" delle vecchie funzioni C
    (hai sono scalfito la punta dell'iceberg)
TaZ++
aka: Roberto Bettazzoni

 wrote in message
8hl4n2$es$1...@zamboni.dsnet.it...
SEI UN MITO!!!!!!!!!!!
Funziona tutto!!!!!!!!!!!!!!!!!!
Mi e' anche chiara la tua spiegazione sul buffer!!!!!!!!!!
Grazie e ciao!!!!!!!!!!!!!!!!!!!!
©Scaccomatto


 Perche'?????
Devi svuotare il buffer di input tra una scanf() e l'altra:
while ( getchar() != '\n' );
EMG
PS. Stai programmando in C.


A dire il vero con cin si presenta lo stesso problema (usando il Borland C++
ed il DJGPP)
Manlio Perillo

 wrote in message 8hlaf0$don$1...@nslave2.tin.it...

Vero.
Il seguente codice è la traduzione (pedissequa) in C++ del problema originale.
--------------- code start
#include <iostream.h>
main()
{
  char parola[10];
  char carattere;
  int x,y;
  cout << "\nInserire la parola: ";
  cin >> parola;
  cout << "\nInserire la coordinata x: ";
  cin >> x;
  cout <<"\nInserire la coordinata y: ";
  cin >> y;
  cout << "\nVerticale od Orizzontale? ";
  cin >> carattere;
// mia aggiunta per visualizzare i dati
  cout << "\n\nhai digitato: \""
    << parola << "\", "<< x
    << ", " << y  << ", carattere \""
    << carattere <<"\"\n";
   return 0;
}
-------------------- end of code
digitando "2w" si ripresenta lo stesso problema (su VC++ e GCC)
------------------ output video
Inserire la parola: pippo
Inserire la coordinata x: 1
Inserire la coordinata y: 2w
Verticale od Orizzontale?
hai digitato: "pippo", 1, 2, carattere "w"
------------------- end output video
Ma il sistema di input e' completamente diverso.
Per il tipo di input che richiedeva l'esempio questo codice risolve il problema degli spazi e dei CR di troppo. Infatti, se non si
commettono errori nella digitazione dei campi, il tutto funziona come "richiesto".
Nota (già che si parla di errori di battitura):
    immetti una stringa più lunga di 10 caratteri e vedi cosa succede !
    questi sistemi di input vanno bene giusto in un esercizio.
TaZ++

 scanf ("\n%c", &carattere);
Veramente ottima idea! Magari se ne dovrebbe parlare in
it.comp.lang.c...
EMG

     (hai sono scalfito la punta dell'iceberg)
Mi dispiace ma entrambi i suggerimenti non sono del tutto corretti. La
funzione fflush() è definita solo per gli output stream e il solo
utilizzo di cin non risolve il problema se non si provvede a svuotare il
buffer o ad utilizzare getline() o simili.
EMG

 Mi dispiace ma entrambi i suggerimenti non sono del tutto corretti.
[CUT]
Eppure a me il comando fflush(stdin) ha risolto il problema!!
©Scaccomatto

 Eppure a me il comando fflush(stdin) ha risolto il problema!!
Ma lo standard non lo prevede e quindi utilizzandolo ti leghi al
particolare compilatore che stai usando e che evidentemente lo prevede
come estensione.
EMG

No, č solo che se fosse capitata una cosa del genere sul lavoro, ed
hai una consegna impellente (o altre cose piů importanti da vedere),
te ne saresti FOTTUTO se non era proprio c++ pulito, o mi sbaglio???
Hai mai lavorato come sviluppatore? Io lo faccio da molto tempo...
Luc.
PS: tutti gli accessi ai file che i nostri programmi aziendali
(scritti in c++), vengono effettuati tramite fprintf e fscanf perchč
sono enormemente piů versatili (ad oggi) degli stream, č ciň che dico
č per esperienza di piů (e valide) persone!
Ciao!


Strano che tutti gli esperti che scrivono abitualmente su
comp.lang.c++.moderated la pensino diversamente...
Ciao,
Nicola

 č per esperienza di piů (e valide) persone!
La mia esperienza (e quella di tante altre "valide persone") e`
esattamente l'opposto.  L'_architettura_ di iostream e` molto
piu` potente e versatile; il geniale disaccoppiamento fra la
formattazione (operator>> ecc) e il buffering (streambuf &c)
permette con estrema facilita` l'estensione, quando e se occorra,
lungo DUE "assi ortogonali":
a. operazioni di I/O formattato su tipi definiti dall'utente,
    che con printf/scanf e famiglia sono un disastro;
b. operazioni di filtraggio (in tutti i sensi) e ridirezione
    dell'input e dell'output formattato, che con printf/scanf
    e famiglia neppure ti sogni.
Internazionalizzazione e localizzazione dell'I/O sono pure
facilitate dal fatto che tutte le classi in gioco sono template
basati sul tipo di caratteri (8-bit o 16-bit) e relativi traits.
Basta che anche gli operator<< ecc da noi scritti siano
similmente template, e il passaggio da I/O in codici ANSI/ISO
a 8 bit, ad I/O in Unicode, diventa una passeggiata.  Non tutti
vendono in Giappone, Corea, ecc, certo, ma per chi vuole davvero
"giocare a tutto campo" sono cose importanti (non credo, giusto
per dare un esempio, che i nostri programmi, per quanto validi,
avrebbero potuto guadagnarsi l'ambito ruolo di "programmi di CAD
meccanico ufficialmente adottati da" [Adidas, Toshiba Motors,
ecc] se non avessero offerto tutta l'interoperabilita` "mondiale"
necessaria a multinazionali di questo calibro).
Non so bene quali aspetti di "enorme versatilita`" tu veda in
printf/scanf e soci, ma immagino che si parli delle "stringhe
di formattazione".  Soprattutto per scanf &c, pero` (input
formattato), un simile "scanner dei poveri" e` appunto... da
poveracci.  Un lexer/scanner (fatto ad esempio con flexx e
byacc, ma ci sono molti altri strumenti analoghi, e altri che
possono essere considerati migliori), con tutta la dovuta
*robustezza* a fronte di errori di formattazione dell'input,
e` una soluzione "di forza industriale" assai preferibile.
Per l'output, la flessibilita` di printf non e` sufficiente,
poiche` l'ordine e il tipo degli argomenti risultano fissi
a tempo di compilazione e l'unico livello di 'flessibilita`'
nella stringa che passi a printf e` del tipo "quante cifre
significative in questo numero, quante in quest'altro"; e`
poco, quando la flessibilita` serve davvero.  Un approccio
piu` flessibile e` esemplificato invece dall'operator% di
Python, quando l'operando di destra e` un mapping; in questo
caso, la stringa di formattazione specifica anche QUALI
elementi disponibili vanno formattati sull'output e in che
ordine, non solo dettagli come il numero di cifre, ecc.
Una implementazione C++ si puo` basare su di un "formatting
object" che puo` venire INIZIALIZZATO con una stringa di
formato, e fornire i necessari operator<< "intelligenti".
(In pratica, preferisco imbeddare direttamente Python, che
e` un'operazione facilissima, e mi consente di riutilizzare
non solo questo aspetto ma tanti, tantissimi altri; ma se
per una qualsiasi ragione Python non e` accettabile, allora
un approccio in termini di "formatting object" potrebbe
secondo me offrire l'architettura migliore).
Alex

 è per esperienza di più (e valide) persone!
Beh, credo proprio che tu e le tue "valide" persone dobbiate rivedere un
pochino le vostre convinzioni... :-)
EMG
PS. Comunque quando ho scritto "ottima idea" parlavo seriamente. Solo
che è una soluzione da adottare quando si programma in C, non in C++.
Tutto qui.

 (e valide) persone!
Potremmo obiettare, ma nascerebbe un thread lungo e litigioso.
Ci limitiamo a contestare in silenzio la tua affermazione.
Fausto

 ....
La prossima volta scrivi 25 anni, che ti fa meno vecchio  :-))))
Altrimenti non ti lamentare se poi in altri post ("Avete creato dei 
programmi?")ti escludono dalla categoria "giovani programmatori".
Fausto

sono enormemente piů versatili (ad oggi) degli stream
Onestamente io trovo gli stream (ed un paio di overloading)
molto piu` comodi e versatili di tante fprintf e fscan...
Paolo
--------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
--------------------------------------------------

ci stai attento ti macchi le mani?
Ah, ah, ah, ah...
Da oggi in poi comincio a collezionarle... chissa` che non ne venga
fuori una "contro-faq" interessante!


 programmi?")ti escludono dalla categoria "giovani programmatori".
Cosi` come l'importante, in generale, e` essere giovani "nel cuore",
nel nostro campo lo e` esserlo "nella CPU", cioe` avere l'ultimissimo
modello da 999 MHz e 1/3...!-)
Alex

Si parla sempre di essere giovani dentro, ma vi accorgerete che in realta´
siamo vecchi dentro quando scopriremo i primi peli bianchi nelle nostre
narici...
Un Maurus stanco dei templates

 Inserendo un numero seguito da invio, nel buffer resta il carattere '\n'.
Però il seguente programma funziona perfettamente senza bisogno di alcun
flush:
#include <iostream>
using namespace std;
int main()
{
    int n;
    cin >> n;
    cout << n << endl;
    char c;
    cin >> c;
    cout << c << endl;
}
Come mai?
EMG
PS. Provato con BC++ 5.5 e DJGPP.

Perche' endl emette un newline *e* fa il flush.
Ciao,
Nicola

flush:
a parte il fatto che endl fa il flush, cin e cout sono "tied" 


 a parte il fatto che endl fa il flush, cin e cout sono "tied"
Scusa ma queste due affermazioni mi sembrano entrambe non corrette.
L'endl fa il flush dell'output, non dell'input (sarebbe alquanto
spiacevole se un'inserimento su cout dopo aver letto un dato da uno
stream me lo svuotasse). Anche lo stato di "tied" tra cin e cout
riguarda il flush dell'output stream. Permette di scrivere cose come
cout << "Scrivi il nome ";
cin >> nome;
con la certezza che il prompt compaia a video al momento giusto.
Inoltre, lo stesso programma così modificato continua a funzionare:
#include <iostream>
using namespace std;
int main()
{
    int n;
    char c;
    cin >> n;
    cin >> c;
    cout << n << '\n';
    cout << c << '\n';
}
E questo credo dimostri come né endl né tied c'entrino.
EMG


Ha ragione, però provi:
int main()
{
    int n;
    cin >> n;
    cout << n << endl;
    char c;
    cin.unsetf(ios::skipws);
    cout << cin.rdbuf()->in_avail() << '\n';
    cin >> c;
    cout << c << endl;
}
Saluti   Manlio Perillo

     cin.unsetf(ios::skipws);
Alt! Benissimo. Bravo. Hai ragione. Non avevo considerato lo skip dei
whitespaces. A posto. Grazie.
EMG