Newsgroup: it.comp.lang.c
Titolo: Dove sbaglio?

Vi riporto il codice di un programma che mi stampa 2 volte la
riga (Errore!: digita 'y' o 'n'.) perche' c = getchar() mi prende anche
lo
'\n'. Potete dirmi come evitare cio' in modo che mi scriva soltanto una
volta la riga suddetta? Grazie.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
#define N 10
int main(void)
{
        char *p, pattern[N], testo[MAX];
        int c,n, i = 0;
  FILE *fp;
        printf("Scrivere il file (massimo %d caratteri):\n\n",MAX);
  while (((c = getchar()) != '?') && (i < MAX-1))
   testo[i++] = c;
  if (i == MAX-1)
   printf("\nAttenzione: la ricerca avverra' solo sui primi %d
caratteri\n\n",MAX);
        testo[i] = '\0';
        while((c = getchar()) != '\n')
                ;
        if ((fp = fopen("testo.txt", "w")) == NULL)
  {
                printf("Problemi per aprire il file\n");
                return 1;
        printf("\nDigitare il pattern da cercare(massimo %d caratteri):
",N);
        printf("\n");
  fgets(pattern, sizeof pattern, stdin);
  n = 0;
  if (p = strchr(pattern, '\n')) /*Restituisce un puntatore (p) alla
fine del pattern */
                *p = '\0';
label1:
  if (p = strstr(testo + n, pattern)) /*Restituisce un puntatore alla
prima occorenza del pattern nel file*/
  {
                printf("Il pattern '%s' e' stato trovato alla posizione
%d.\n",
                       pattern, p - testo + 1);
    n = p - testo + 1;
        }
  else
                puts("Pattern inesistente");
  puts ("\nVuoi continuare la ricerca? (y/n)\n");
label2:
  c = getchar();
  printf("\n");
  if (c == 'y')
   goto label1;
  else if (c == 'n')
   exit (0);
  else
   puts("\nErrore!: digita 'y' o 'n'.\n");
  goto label2;
  fclose(fp);
  return 0;
}

 volta la riga suddetta?
In generale il problema è illustrato dal seguente esempio:
#include <stdio.h>
int main()
{
    int c;
    do
    {
        printf( "Inserisci un carattere (0 per finire): " );
        c = getchar();
        printf( "Hai premuto %c\n", c );
    }
    while ( c != '0' );
    return 0;
}
Come si può vedere provandolo, la prima volta funziona tutto bene ma
dalla seconda in poi il messaggio esce sempre due volte. Come mai? La
causa è che io premo il carattere richiesto dal programma seguito dal
tasto INVIO. Se premessi l'EOF (CTRL-Z in DOS) dopo ogni carattere
allora andrebbe tutto bene. L'INVIO che premo è letto come fosse un
qualunque carattere dalla getchar() successiva che quindi pensa che
abbia già terminato l'inserimento e restituisce il controllo al
chiamante che prosegue mostrando nuovamente il messaggio.
Come lo risolvo? Devo svuotare l'input prima di fare una nuova lettura.
Non c'è un metodo perfetto e portabile per far ciò ma una cosa del
genere potrebbe funzionare in molti casi:
void SvuotaInput()
{
    int c;
    do
    {
        c = getchar();
    }
    while ( c != '\n' );
}
 
Comunque nel programma che hai riportato ci sono altri errori:
1. Manca la parentesi graffa chiusa nel secondo if.
2. L'espressione p - testo + 1 è di tipo long mentre nella stringa di
formato della printf() in cui è contenuta c'è %d invece che %ld (non so
se questo cambi da un compilatore all'altro).
3. L'istruzione fclose() non viene mai eseguita.
4. L'uso dei goto nel tuo caso è altamente sconsigliabile.
EMG