[C] Leggere piu' righe da stdin

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
joseph
Linux 2.x
Linux 2.x
Messaggi: 206
Iscritto il: lun 14 giu 2010, 23:50
Slackware: 15.0
Kernel: 5.15.27
Desktop: xfce
Località: Salerno

[C] Leggere piu' righe da stdin

Messaggio da joseph »

Ciao ragazzi, sto facendo un piccolo programmino in C, ho un piccolo problema.
Praticamente ho l'esigenza di leggere da stdin piu' righe, ad esempio

Ciao
mi chiamo
Marco.

ho scritto questo codice:

Codice: Seleziona tutto

             printf("\n\n------------- Incollare il testo qui sotto -------------\n");
             while(fgets(messaggio,buff_size,stdin){
                 if(messaggio[0]=='\n')
                     break;
                 operazioni....
             }
             printf("------------- Fine del testo incollato -------------\n\n");
in pratica la fgets mi legge una riga per volta fin quando non finisce lo stdin.
Il problema che dopo l'ultima riga il cursore si ferma su fgets e se non premo invio
(condizione if verificata) non esce dal ciclo...C'è un sistema automatico che quando
lo stdin è vuoto in automatico esce dal ciclo?
Grazie a tutti ragazzi :)

Avatar utente
ulisse89
Packager
Packager
Messaggi: 643
Iscritto il: sab 17 gen 2009, 12:53
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce
Località: Bologna

Re: [C] Leggere piu' righe da stdin

Messaggio da ulisse89 »

Se da standard input digiti CTRL-D (che equivale a EOF), allora il tuo ciclo termina in automatico, anche se togli la condizione if.

La fgets ritorna già NULL quando c'è una riga vuota.
Però tu quando digiti solo INVIO non passi una riga vuota ma una riga con un carattere singolo ('\n').
Per passare una riga vuota devi digitare CTRL-D e nient'altro.

Avatar utente
joseph
Linux 2.x
Linux 2.x
Messaggi: 206
Iscritto il: lun 14 giu 2010, 23:50
Slackware: 15.0
Kernel: 5.15.27
Desktop: xfce
Località: Salerno

Re: [C] Leggere piu' righe da stdin

Messaggio da joseph »

Quindi devo usare per forza il CTRL+D ?

Avatar utente
ulisse89
Packager
Packager
Messaggi: 643
Iscritto il: sab 17 gen 2009, 12:53
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce
Località: Bologna

Re: [C] Leggere piu' righe da stdin

Messaggio da ulisse89 »

joseph ha scritto:Quindi devo usare per forza il CTRL+D ?
No, io non ne so molto di C, può essere che esista qualcosa che io non conosco.

Tu vorresti che quando digiti INVIO in una riga senza nient'altro, esca dal ciclo senza aver messo la condizione if?

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [C] Leggere piu' righe da stdin

Messaggio da Mario Vanoni »

Guarda bc(1), calcola quante righe vuoi,
con la parola chiave "quit" esce.

Quindi
programma
riga 1
riga 2
...
riga n
quit

Avatar utente
joseph
Linux 2.x
Linux 2.x
Messaggi: 206
Iscritto il: lun 14 giu 2010, 23:50
Slackware: 15.0
Kernel: 5.15.27
Desktop: xfce
Località: Salerno

Re: [C] Leggere piu' righe da stdin

Messaggio da joseph »

In pratica vorrei che dopo aver inserito le multi righe e aver premuto invio, mi esca il risultato dell'operazione che va a effettuare.
Invece per il momento inserisco le multirighe, premo invio, mi esce il risultato però dopo il risultato mi si blocca il prompt sull'fgets (cosa che non voglio) al posto di rientrare il prompt!

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [C] Leggere piu' righe da stdin

Messaggio da targzeta »

La domanda che ti devi porre è:"come fa il programma a capire che l'utente ha finito di scrivere?" Per ora ti sei dato una risposta: "quando inserisce la riga vuota". Eistono altre risposte diverse?

Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
joseph
Linux 2.x
Linux 2.x
Messaggi: 206
Iscritto il: lun 14 giu 2010, 23:50
Slackware: 15.0
Kernel: 5.15.27
Desktop: xfce
Località: Salerno

Re: [C] Leggere piu' righe da stdin

Messaggio da joseph »

Ok allora chiedo: Eistono soluzioni diverse?

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [C] Leggere piu' righe da stdin

Messaggio da Mario Vanoni »

joseph ha scritto:Ok allora chiedo: Eistono soluzioni diverse?
Se il numero delle righe da immettere ha un valore massimo, si`.
Conti le righe e, raggiunto il massimo, il programma termina fgets,
continua con la prossima operazione, se non disturbano righe vuote.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [C] Leggere piu' righe da stdin

Messaggio da targzeta »

Lo stdin è un buffer che generalmente è bloccante, ciò vuol dire che quando vai a leggere dallo stdin se non c'è scritto niente vieni bloccato. Se modifichi questo comportamento però ottieni il risultato contrario, ovvero tu vai a leggere ma se l'utente non ha scritto ancora niente (che si traduce con "non ha premuto enter") tu non leggi nulla. Tutti i programmi che si interfacciano verso lo stdin devo sapere quando l'input è terminato, nel tuo caso hai deciso che l'input termina quando l'utente inserisce una riga vuota. Sta a te trovare delle caratteristiche che segnalano la fine dell'input.

In teoria puoi fare qualsiasi cosa: mettere la read non bloccante, inserire un timeout, ma ti complichi solo la vita. La tua soluzione è corretta, uno prima scrive tutto, poi inserisce una riga vuota e il tuo programma esce dal loop.

Lo stdin lo devi vedere come una pipe o un socket, è un flusso di byte non è un insieme predefinito di byte con un inizio e una fine. Tu puoi leggere, ma se non c'è scritto niente allora aspetti che qualcuno ti scriva, devi sapere tu quando non devi fare la lettura.

Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
ulisse89
Packager
Packager
Messaggi: 643
Iscritto il: sab 17 gen 2009, 12:53
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce
Località: Bologna

Re: [C] Leggere piu' righe da stdin

Messaggio da ulisse89 »

joseph ha scritto:In pratica vorrei che dopo aver inserito le multi righe e aver premuto invio, mi esca il risultato dell'operazione che va a effettuare.
Invece per il momento inserisco le multirighe, premo invio, mi esce il risultato però dopo il risultato mi si blocca il prompt sull'fgets (cosa che non voglio) al posto di rientrare il prompt!
Ancora non capisco bene.
La soluzione che hai proposto, presuppone che:
- scrivi una riga
- premi invio
- il programma effettua le operazioni sulla riga letta
- ritorna al prompt e digiti la riga successiva

Quando non vuoi più digitare niente, digiti invio al prompt e basta.
Così esce dal ciclo.

Se vuoi che legga prima tutte le righe e POI ti dia il risultato finale, allora dovresti come minimo allocare un vettore di stringhe in cui mettere le righe lette.
Quindi presuppore un massimo di righe da leggere.

Rispondi