Fermare loop con tasto invio [C]

di Anonimizzato14501 il
15 risposte
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

  • 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;
    }
    
  • 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
  • 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)
  • 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.
  • E se la stringa e' di 99 caratteri ( 100 con il '\0' ) e ne aggiungi uno? dove va a finire?
  • Ultimo diffettuccio : Hai provato a inserire una stringa di un solo carattere?
  • 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!
  • Ah beh quello sì. Davo per scontato che la stringa fosse di dimensioni umane!
    ahahahahahhahahahahahahhahahahahahahahahhaha
  • 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.

  • 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;
    }
    
  • 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.
  • 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.
  • 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
  • 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