Newsgroup: it.comp.lang.c
Titolo: [NEWBIE] Problema con scanf

Ciao a tutti,
È un po' di tempo che sto cercando di imparare il C. Mentre tentavo di 
fare un programmino con dei cicli for ho notato una strana anomalia in 
scanf. In poche parole le prime due istruzioni funzionano correttamente, 
ma l'ultima viene saltata. Ecco il pezzo di codice incriminato:
#include <stdio.h>
int main(void)
{
   int numero1,numero2;
   char carattere;
   printf("Inserisci un numero: ");
   scanf("%d",&numero1);
   printf("Inserisci un altro numero: ");
   scanf("%d",&numero2);
   printf("Inserisci un carattere: ");
   scanf("%c",&carattere); //Istruzione che viene saltata
   printf("Carattere: %c\n",carattere);
   return 0;
}
Ed ecco l'output che mostra in shell:
$ cc prova.c -Wall
$ ./a.out
Inserisci un numero: 3
Inserisci un altro numero: 4
Inserisci un carattere: Carattere:
Compilato usando gcc 4.1.2 su Debian Sid. GNU Emacs come editor.
Ho provato anche con "carattere = getchar" ma non funziona. Invece 
usando %s come formattatore di campo nello scanf sembra andare, ma alla 
fine mi da un errore di segmentazione: segmentation fault (core dumped).
Cos'è che non funziona?
Ciao, Costantino
-- 
Linux non è un sistema operativo, ma un modo diverso per affrontare la 
propria esistenza.
http://linuxrevenge.wordpress.com/
Powered by:
  _____       _     _                _____ _     _
|  __ \     | |   (_)              / ____(_)   | |
| |  | | ___| |__  _  __ _ _ __   | (___  _  __| |
| |  | |/ _ \ '_ \| |/ _` | '_ \   \___ \| |/ _` |
| |__| |  __/ |_) | | (_| | | | |  ____) | | (_| |
|_____/ \___|_.__/|_|\__,_|_| |_| |_____/|_|\__,_|
linux 2.6.23.1-handmaded

 scanf. 
Se avessi ricevuto mezzo centesimo per ogni volta che ho consigliato ai
"newbie" di buttare via la scanf(), preferendo fgets(), oggi sarei
miliardario. Devi intervallare le lettura con scanf() da un ciclo che
svuoti il buffer di tastiera. Ti consiglio di scrivere una funzione:
void flushKeybBuff() {
   while (getchar()!='n')
        ;
}
e invocarla dopo ogni scanf().
L'alternativa č, appunto, usare fgets() (che richiede un pochetto di
lavoro in piů, ma č piů sicura e meno problematica).
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 lavoro in piů, ma č piů sicura e meno problematica).
Si...ok.
Ho letto la parte relativa fgets sia sul K&R, sia sul manuale che sto 
usando (Linguaggio C - McGraw-Hill) e ho lurkato un po' per il ng. Dice 
che č una variante di gets, implementata perché gets non controlla la 
lunghezza dei dati in input e potrebbe causare buffer overflow. Right?
Il problema č che io sono proprio alle prime armi e non saprei proprio 
come usarla XD. Non č che potresti postarmi il programmino fatto con fgets?
Grazie mille!
Ciao, Costantino
P.S. Sarebbe meglio usare anche fputs al posto printf?
-- 
Linux non č un sistema operativo, ma un modo diverso per affrontare la 


 come usarla XD. Non è che potresti postarmi il programmino fatto con fgets?
E' facile scrivere una funzione basata su fgets() (vado al volo, senza
compilare):
#include <stdlib.h>
#include <string.h>
char *readString(const size_t maxDim) {
     char *result = malloc(maxDim+1);
     if (result) { 
        size_t len;
        fgets(result, maxDim, stdin);
        len = strlen(result);
        if (result[len-1] == 'n') 
           result[len-1] = '

Andrea Laforgia ha scritto:

ehm...
Quando dicevo alle prime armi intendevo veramente alle prime armi!
Ovvero...non so cosa siano puntatori, dichiarazioni di funzioni, 
stringhe, array e compagnia bella.
Vabbè, fa niente, rinvio questo stupido programmino a quando sarò più 
esperto.
Grazie per l'aiuto!
Ciao, Costantino
-- 
Linux non è un sistema operativo, ma un modo diverso per affrontare la 


Quando dicevo alle prime armi intendevo veramente alle prime armi!
Scusa, ma newsland taglia i messaggi perché interpreta le sequenze di
escape (bah.. che sistema balordo di gestire i newsgroup).
La funzione corretta, comunque, la trovi nel thread sul reversing di
una stringa a cui ho risposto.

 e invocarla dopo ogni scanf().
Sorry per la domanda banale forse ma... questo ciclo cosa fa? Controlla che
il valore di getchar() sia diverso da n... anche se forse intendevi \n.
Quando č uguale a \n, si passa alle istruzioni successive?
Anche pensando alla tua risposta al mio precedente thread, ho cercato di
scrivere questo programma semplice:
#include <stdio.h>
#include <stdlib.h>
int main()
{
  char string1, string2;
  printf("Inserisci il carattere da memorizzare in string1\n");
  scanf("%c", &string1);
  void flushKeybBuff();
  printf("Inserisci il carattere da memorizzare in string2\n");
  scanf("%c", &string2);
  printf("string1 vale %c e string 2 vale %c\n", string1, string2);
  system("PAUSE");	
  return 0;
}
void flushKeybBuff() {
   while (getchar()!='n')
        ;
}
Dopo aver inserito il valore per string1 e schiacciato invio, il programma
mi passa alla seconda printf, poi non attende per la scanf successiva, e
stampa la terza printf senza, ovviamente, nessun valore per string2.
Se invece inserisco, al posto di void flushKeybBuff(); semplicemente
getchar(); allora funziona.
Perché?
Rocky3
-- 
"Il sapere e la ragione parlano, l'ignoranza ed il torto urlano".
Arturo Graf / Indro Montanelli / Anonimo

   void flushKeybBuff();
Questa invocazione è sbagliata: togli quel void.


 una stringa a cui ho risposto.
Trovata.
char *getString(size_t sz) {
      char *result = malloc(sz+1);
      if (result) {
         size_t len;
         fgets(result, sz+1, stdin);
         len=strlen(result);
         if (result[len-1]=='\n')
           result[len-1]='\0';
      }
      return result;
}
Il problema è che non sapendo minimamente cosa fa e come funziona mi 
scoccia includerla nei miei programmi. Comunque visto che 
flushKeybBuff() funziona alla grande per ora uso quella. Prendo atto del 
consiglio che metterò in pratica quando riuscirò a capire il source.
:D
Grazie, Costantino


          len=strlen(result);
Memorizza la lunghezza della stringa letta in len (nonostante la
dimensione massima passata potrebbe essere sz=50, il numero di caratteri
letti potrebbe essere inferiore).
