Repository 32bit  Forum
Repository 64bit  Wiki

[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.

[C] Leggere piu' righe da stdin

Messaggioda joseph » ven lug 02, 2010 12:47

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
joseph
Linux 2.4
Linux 2.4
 
Messaggi: 205
Iscritto il: lun giu 14, 2010 22:50
Località: Salerno
Slackware: 13.37
Kernel: 3.2.9
Desktop: xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda ulisse89 » ven lug 02, 2010 13:26

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
ulisse89
Packager
Packager
 
Messaggi: 644
Iscritto il: sab gen 17, 2009 12:53
Località: Bologna
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda joseph » ven lug 02, 2010 13:47

Quindi devo usare per forza il CTRL+D ?
Avatar utente
joseph
Linux 2.4
Linux 2.4
 
Messaggi: 205
Iscritto il: lun giu 14, 2010 22:50
Località: Salerno
Slackware: 13.37
Kernel: 3.2.9
Desktop: xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda ulisse89 » ven lug 02, 2010 13:59

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?
Avatar utente
ulisse89
Packager
Packager
 
Messaggi: 644
Iscritto il: sab gen 17, 2009 12:53
Località: Bologna
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda Mario Vanoni » ven lug 02, 2010 14:04

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

Quindi
programma
riga 1
riga 2
...
riga n
quit
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] Leggere piu' righe da stdin

Messaggioda joseph » ven lug 02, 2010 14:06

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
joseph
Linux 2.4
Linux 2.4
 
Messaggi: 205
Iscritto il: lun giu 14, 2010 22:50
Località: Salerno
Slackware: 13.37
Kernel: 3.2.9
Desktop: xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda targzeta » ven lug 02, 2010 14:15

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: [C] Leggere piu' righe da stdin

Messaggioda joseph » ven lug 02, 2010 14:23

Ok allora chiedo: Eistono soluzioni diverse?
Avatar utente
joseph
Linux 2.4
Linux 2.4
 
Messaggi: 205
Iscritto il: lun giu 14, 2010 22:50
Località: Salerno
Slackware: 13.37
Kernel: 3.2.9
Desktop: xfce

Re: [C] Leggere piu' righe da stdin

Messaggioda Mario Vanoni » ven lug 02, 2010 14:34

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.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] Leggere piu' righe da stdin

Messaggioda targzeta » ven lug 02, 2010 14:35

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: [C] Leggere piu' righe da stdin

Messaggioda ulisse89 » ven lug 02, 2010 14:42

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.
Avatar utente
ulisse89
Packager
Packager
 
Messaggi: 644
Iscritto il: sab gen 17, 2009 12:53
Località: Bologna
Nome Cognome: Riccardo
Slackware: 13.0
Kernel: 2.6.29.6
Desktop: Xfce


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite