Newsgroup: it.comp.lang.c
Titolo: while ((ccc = getchar()) != '\n')

Salve a tutti,
Ho in problema con la getchar (sono un principiante), mi aspettavo che
con l'istruzione in oggetto si fermasse il programma in attesa
dell'input, ma invece prosegue. Devo dire che il programma, nella
variabile ccc, ha gia' dentro il valore '\n': come faccio a fermare il
programma fino a che l'utente inserisce un valore ?
Grazie in anticipo
Ciao
Marco
/**********************************************
 *
 * lista dinamica      Marco dicembre 2006
 *
 **********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX   4
/**********************************************************/
struct part {	int number;
		char *name;
} mioarray[MAX] ={
		 {1, "Aggiungi elementi in automatico"},
		 {2, "Aggiungi elemento"},
		 {3, "Stampa lista"},
		 {4, "Fine Programma"},
		 };
struct part *p_part;
/**********************************************************/
/*** definizione lista ****/
struct	tag_lista {char valore;
		   struct tag_lista *next;
	};
struct tag_lista elemento;
typedef struct tag_lista* plista;
plista punt_first_elem=NULL;
plista punt_next_elem=NULL;
/**************************/
/*** prototipi di funzioni ****/
plista aggiungi_elemento_automatico(plista);
plista aggiungi_elemento(plista);
int  stampa_lista(plista);
int  fine();
int  dim_lista=0;
/*************************************/
int main()
/*************************************/
{
  int choice=0, count;
  while (1){
	p_part = mioarray;
	for (count = 0; count < MAX; count++){
		printf("%d - %s\n", p_part->number, p_part->name);
		p_part++;
	}
	if (dim_lista !=0){
	    printf("\n*********************************");
	    printf("\n Dimensione lista => %d", dim_lista);
	    printf("\n*********************************");
	}
	printf("\nSelezionare scelta: ");
	scanf("%d", &choice);
	/*printf("\nScelta %d \n", choice);*/
	switch (choice) {
        case 1:
	     if (punt_first_elem==NULL) { /* se primo elemento della lista */
	         punt_first_elem=aggiungi_elemento(punt_first_elem);
	         punt_next_elem=punt_first_elem;
punt_next_elem=aggiungi_elemento_automatico(punt_next_elem);
	     }
	     else{
		printf("\n");
		printf("Funzione non piu' utilizzabile:\n");
		printf("E'possibile inizilizzare automaticamente la tabella solo
all'inizio della procedura\n");
		printf("\n");
	     }
             break;
        case 2:
	     if (punt_first_elem==NULL) { /* se primo elemento della lista */
	         punt_first_elem=aggiungi_elemento(punt_first_elem);
	         punt_next_elem=punt_first_elem;
	     }
	     else{
                 punt_next_elem=aggiungi_elemento(punt_next_elem);
	     }
             break;
        case 3:
	     stampa_lista(punt_first_elem);
             break;
        case 4:
             break;
        default:
             printf( "Wrong choice !!!!\n");
             return -1;
             break;
	}
	if (choice == 4) {
	   break;
	}
  }
return 0;
}
/*************************************
 * Allocazione nuovi elementi
 *************************************/
plista aggiungi_elemento(plista pold)
{
  int ccc;
  plista pnew;
  pnew=(plista) malloc(sizeof(elemento));
  pnew->next=NULL;       /*inizilizzazione con NULL del nuovo
elemento*/
  if  ( pold==NULL){     /*se primo elemento delle lista*/
        pnew->valore='\0';
        while (!isalpha(pnew->valore)){
              pnew->valore=((pnew->valore) + 1);  /*valore
dell'elemento vecchio + 1 */
        }
  }
  else{
	/*qui non si ferma*/
        printf("Inserire carattere=> ");
        while ((ccc = getchar()) != '\n'){
	      pnew->valore=ccc;
        /* pnew->valore=((pold->valore) + 1);  valore dell'elemento
vecchio + 1 */
              pold->next=pnew;                    /*inserimento del
puntatore dell'elemento precedente */
        }
	printf("\nint=>%d\n", ccc);
  }
  printf("\nvalore: %d (int) %c (char)\n", pnew->valore, pnew->valore);
  return pnew;
}
/*************************************
 * Allocazione nuovi elementi automaticamente
 *************************************/
plista aggiungi_elemento_automatico(plista pold)
{
  plista pnew;
  do {
     pnew=(plista) malloc(sizeof(elemento));
     pnew->next=NULL;     /*inizilizzazione con NULL del nuovo
elemento*/
     pnew->valore='\0';   /*inizilizzazione con NULL del nuovo
elemento*/
     pnew->valore=((pold->valore) + 1);  /*valore dell'elemento vecchio
+ 1 */
     while (!isalpha(pnew->valore))
         pnew->valore=((pnew->valore) + 1);  /*valore dell'elemento
vecchio + 1 */
     pold->next=pnew;                    /*inserimento del puntatore
nell'elemento precedente */
     pold=pnew;
  }  while(pnew->valore != 'z' );
  return pnew;
}
/*************************************
 *
 *************************************/
int stampa_lista (plista punt)
{
plista p;
int ctr=1;
p=punt;
  while(1){ /*ciclo infinito */
        if (p->next != NULL ){
	   printf("%3c%c", p->valore, ctr%10 == 0 ? '\n' : ' ');
           p=p->next;
           ctr++;
	}
	else{
	   printf("%3c%c", p->valore, '\n');
	   break;
	}
  }
  printf("\n\n");
  printf("Elementi in memoria.....>%d \n", ctr);
  printf("Sizeof elemento.........>%d \n", sizeof(elemento));
  printf("Sizeof elem. char ......>%d \n", sizeof(p->valore));
  printf("Sizeof elem. punt ......>%d \n", sizeof(p->next));
  printf("\n");
  return 3;
}

programma fino a che l'utente inserisce un valore?
Ho dato un occhio veloce alla aggiungi_elemento e ho notato che
non usi il parametro pold, immagino servisse qui, altrimenti il
codice non ha senso:
pnew->valore = '\0';
while (!isalpha (pnew->valore))
   pnew->valore = ((pnew->valore) + 1);
Il getchar e' corretto, si ferma ad attendere l'input
dell'utente, ma in qualsiasi caso ritorna \n in quanto esso e'
l'ultimo carattere letto dal buffer di input.
Devi trovare un approccio diverso, ad esempio:
char s [10];	// Attento, e' sottodimensionato!
scanf("%s",s);
ccc = s [0];

Goodidea ha scritto:

Effettivamente come hai detto tu, funziona. Ti ringrazio molto.
Volevo anche chiederti cosa è sottodimensionato? Il campo "ccc" che
oltre a contenere il valore digitato dall'utente contiene anche il '\0'
? E se cosi' fosse, non dovrei trovarmi solo il carattere digitato
perdendomi il resto ovvero '\0'  ?
Grazie ancora
Ciao.

 ccc = s [0];
se proprio si vuole usare la scanf [1], in questo caso e' meglio 
limitarne il numero di caratteri che legge per evitare un buffer overflow:
eg: char s[10]; scanf("%9s", s);
(esistono tecniche per parametrizzare la lunghezza [2])
note: (tutte faq)
[1] 
http://c-faq.com/stdio/scanfprobs.html
[2] 
http://c-faq.com/stdio/scanfvwid.html
Ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

fatto un post)
Era solo una battuta amara... ;(
Preferisco sempre essere il piu' completo possibile nelle mie
risposte (vedi il sorgente che ho riscritto in "Calcolo area
poligono"), mi danno un po' fastidio quelli che notano una
imperfezione nel marasma e pensano di aver risolto il problema,
purtroppo l'informatica e' matematica pura: non e' un'opinione...
E' anche se il niubbo e' un misero studente che prende il
compitino fatto e lo passa direttamente al prof, sono sempre
convinto che lavori completi restano in rete ad aiutare altri
"bisognosi".
Grazie per la rispolverata sulla sscanf !

 "bisognosi".
...e' anche per questo motivo che - quando posso e riesco a dedicare del 
tempo - provo a dare un contributo...
PS: Ho visto solo ora che nel sorgente che hai riscritto in "Calcolo 
area poligono" ci sono alcune cose da mettere a posto... Per il motivo 
che hai appena detto (ovvero che rimangono in rete), prova a 
riguardarlo: sicuramente alcuni li hai fatti per la fretta...


riguardarlo: sicuramente alcuni li hai fatti per la fretta...
Probabilmente ti riferisci ai %lf...
Purtroppo ci si abitua alle benevolenza del proprio compilatore
che tollera e perdona molte inesattezze (gravi). Lavorando col
VC6 dovrei affermare che il C non lo conosco affatto e programmo
con un ibrido per la piattaforma Windows.
Aggiungo che tendo sempre e modificare il meno possibile la
struttura del codice originale per evitare che l'autore non
riconosca le modifiche.

 riconosca le modifiche.
...ammiro il tuo intento ma, *personalmente*, la ritengo una tecnica 
sbagliata a priori. Se il codice (dell'autore del post) fosse gia' 
scritto e strutturato in modo errato, perseverare in quella direzione 
(con la propria benedizione, visto che lo riscrivi identico) e' solo 
dannoso. Non fai un favore ne' alla persona che aiuti, ne' a quelli che, 
seguendo il ng, pensano di imparare qualcosa in piu' dagli esempi.
In molti casi e' quindi meglio far notare (oppure riscrivere) solamente 
le parti di codice o le istruzioni palesemente sbagliate.
(ovviamente tutto questo, sempre e comunque, IMHO)
