Fermare loop con tasto invio [C]

di il
15 risposte

Fermare loop con tasto invio [C]

Salve a tutti

a giugno devo dare l'esame di programmazione 1 e quindi sono alle primissime armi. ho un esercizio in cui mi si chiede "scrivete un programma che legga in ingresso una stringa inserita dall’utente, e la riscriva tale e quale sulla console. l’esecuzione deve continuare in questo modo fino a che l’utente non prema subito invio senza scrivere altro."

io ho scritto questo codice che parte ma non si ferma mai:

# include <stdio.h>
# include <math.h>
# include "Prog1/IO.h"

int main (void)

{
	String s;
	char c;
	
	printf("inserisci una stringa >\t");
	leggi_str(s,s);
	 
	do	
		{
		while (1)
		printf("%s\n",s);
		}
	while (c=getchar()=='/');		

	return 0;
}
non so affatto come chiamare il tasto invio. se provo c=getchar()=='13' cioè 'invio' in ASCII non compila e restituisce "warning: multi-character character constant". se metto c=getchar()=="\n" idem come sopra con errore "warning: comparison between pointer and integer". insomma niente.

mi aiutate? grazie.

15 Risposte

  • Re: Fermare loop con tasto invio [C]

    Ciao,
    in effetti il problema non mi sembrava banale (probabilmente per qualcuno lo è...)
    Ti posto una possibile soluzione, ampiamente commentata. Penso però che si possa fare di meglio! Quindi forse ti conviene aspettare risposte da parte di utenti più esperti, però intanto puoi dare un'occhiata a queste poche righe.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    
    /* funzione che "sposta" la stringa in avanti di una
       posizione e aggiune un carattere in testa */
    void shiftAndAdd(char * stringa, char c)
    {
        int size = strlen(stringa);    /* lunghezza della stringa */
        char * nuova = (char *) malloc(size + sizeof(char));   /* la nuova stringa: la dimensione e' quella della vecchia piu' la dimensione di un char */
        strcpy(nuova+sizeof(char), stringa);        /* copio la vecchia stringa piu' avanti dentro alla nuova: l'offset e' pari alla dimensione di un char */
        nuova[0] = c;           /* aggiungo il carattere in testa */
        strcpy(stringa, nuova);     /* rimetto tutto dentro la vecchia stringa */
    }
    
    int main()
    {
        char stringa[100];
        char c;
    
        while(1)
        {
            printf("Inserisci una stringa >\t");
            c = _getch();           /* legge un carattere senza attendere la pressione di Invio */
            if(c==13) break;        /* premuto Invio */
            else putchar(c);        /* stampo il carattere sullo schermo */
            scanf("%s", stringa);   /* leggo il resto della stringa */
            shiftAndAdd(stringa, c);    /* aggiungo il carattere in testa */
            printf("Hai inserito \"%s\".\n", stringa);
        }
    
        printf("\nInserimento terminato.\n");
        return 0;
    }
    
  • Re: Fermare loop con tasto invio [C]

    do
    {
    while (1) <-----------------
    printf("%s\n",s);
    }
    while (c=getchar()=='/');
    il while(1) ripete l'istruzione successiva infinite volte. Sicuramente devi toglierlo.
    Inoltre invio e' '\n' , non '\'

    Poi, dato che non credo tu conosca funzioni come kbhit() o GetAsyncKeyState() o simili, credo che il testo intendesse che devi inserire la stringa e stamparla 1 volta, inserirne un'altra e stampare la nuova, ecc... finchè non inserisci una stringa vuota. a quel punto termini il programma.

    Suggerimento: basta un controllo sul primo carattere
  • Re: Fermare loop con tasto invio [C]

    char * nuova = (char *) malloc(size + sizeof(char)); /* la nuova stringa:
    Se sai che la grandezza di un carattere e' 1 byte, puoi scrivere direttamente " size + 1".
    Altrimenti devi moltiplicare size x la grandezza di un char "size*sizeof(char) + sizeof(char)"

    strcpy(nuova+sizeof(char), stringa); /* copio
    e' deprecated. Meglio strncpy()

    strcpy(stringa, nuova); /* rimetto tutto dentro la vecchia stringa */
    Non hai riallocato "stringa" (overflow)
  • Re: Fermare loop con tasto invio [C]

    ale99 ha scritto:


    strcpy(stringa, nuova); /* rimetto tutto dentro la vecchia stringa */
    Non hai riallocato "stringa" (overflow)
    Ciao,
    non ho capito perché devo riallocare stringa. Se non sbaglio, per come l'ho dichiarata, dovrebbe esserci spazio sufficiente per 100 caratteri, quindi se ne aggiungo uno non dovrebbe succedere nulla. O sbaglio qualcosa?

    Grazie delle informazioni.
  • Re: Fermare loop con tasto invio [C]

    E se la stringa e' di 99 caratteri ( 100 con il '\0' ) e ne aggiungi uno? dove va a finire?
  • Re: Fermare loop con tasto invio [C]

    Ultimo diffettuccio : Hai provato a inserire una stringa di un solo carattere?
  • Re: Fermare loop con tasto invio [C]

    ale99 ha scritto:


    e se la stringa e' di 99 caratteri ( 100 con il '\0' ) e ne aggiungi uno? dove va a finire?
    Ah beh quello sì. Davo per scontato che la stringa fosse di dimensioni umane!
  • Re: Fermare loop con tasto invio [C]

    Ah beh quello sì. Davo per scontato che la stringa fosse di dimensioni umane!
    ahahahahahhahahahahahahhahahahahahahahahhaha
  • Re: Fermare loop con tasto invio [C]

    Innanzitutto grazie ad entrambi per le risposte.

    il codice di minomic mi è assolutamente incomprensibile (siamo alla 5° lezione partendo da zero) quindi credo di aver interpretato male la richiesta dell'esercizio.

    non ho il compilatore su questo pc, lunedì proverò il suggerimento di ale99 e vi dico.

    rigrazie.

  • Re: Fermare loop con tasto invio [C]

    Mimonic è incomprensibile!

    ma ragazzi? leggere una stringa e ripeterla!
    
    #define MAX 100
    
    int main(void)
    {
        char line[MAX];
    
        while( 1 )
        {
            fgets(line,MAX,stdin);
                if (line[0] == '\n') break;
            puts(line);
        }
    
        return 0;
    }
    
    per i puristi del c diventa:
    
    #define MAX 100
    
    int main(void)
    {
        char line[MAX];
    
        while( fgets( line, MAX, stdin) && line[0] != '\n' )
            puts(line);
    
        return 0;
    }
    
  • Re: Fermare loop con tasto invio [C]

    Vb credo che il tuo codice non funzioni nel senso dell'esercizio, eseguendo ./a.out e scrivendo un stringa subito dopo che si è avviato il programma ripete la stringa e termina.

    ad ogni modo deve esserci una soluzione ancora più sempliciotta perchè fgets e puts sono funzioni che non abbiamo ancora trattato.

    grazie comunque.
  • Re: Fermare loop con tasto invio [C]

    Veramente il programma é testato e quindi non capisco il perché delle tue affermazioni.Provero a ripetere il test.ma hai incluso gli header? Visto che non conosci le funzioni forse no....

    Quella é la maniera piu semplice, se non conosci tali funzioni allora sarà il caso che tu ci dica quali funzioni conosci.
  • Re: Fermare loop con tasto invio [C]

    In effetti il codice di vbextreme funziona perfettamente, l'unica cosa da ricordare è che fgets inserisce anche un '\n' alla fine della stringa quindi per rimuoverlo basta fare una roba tipo:
    line[strlen(line)-1]='\0';
    Comunque se l'OP non conosce la fgets può benissimo sostituirla con una qualsiasi funzione fatta in casa per leggere le stringhe, mentre per la puts direi che non ci sono problemi visto che è addirittura più banale della printf e può essere benissimo sostituita da quest'ultima
  • Re: Fermare loop con tasto invio [C]

    Ocio non ho detto che non compila ho detto che non mi pare sia quello che l'esercizio richiede.

    comunque al di là dell'esercizio adesso mi sono fissato con questo problema.

    voglio un codice che chieda di inserire una stringa e che la ripeta all'infinito (tipo while(1)). quando ad un certo punto l'utente preme invio il programma si chiude.

    è fattibile?

    grazie a tutti.
Devi accedere o registrarti per scrivere nel forum
15 risposte