Newsgroup: it.comp.lang.c
Titolo: Stringhe

Salve a tutti e grazie anticipatamente.
Vi espongo il mio problema
Devo leggere un testo 10x20 (10 righe e 20 colonne), vorrei che la 
digitazione da parte dell'utente si interrompesse nel momento in cui ha 
inserito il penultimo carattere ho inserito queste istruzioni
for (i=0;i<MAXLINE-1 || (c=getchar())!=EOF && c!='\n';i++)
     longest[i]=c;
longest[MAXLINE]='\0';
Ma la lettura continua ll'infinito
Ancora grazie 

 longest[MAXLINE]='\0';
 for (i=0;i<MAXLINE;i++)
   if ((c=getchar())!=EOF && c!='\n')
     longest[i]=c;
   else
     break;
 longest[i]=0;
 if (i==MAXLINE) /* letto MAXLINE caratteri senza \n o EOF */
   while ((c=getchar())!=EOF && c!='\n');
-- 
Horst

 longest[MAXLINE]='\0';
...
Non hai detto come e'  dichiarato longest. Non e'  che per caso lo 
spazio allocato a longest e' MAXLINE ???
Giorgio

 ha scritto nel messaggio 
news:q47o31pa86l5mjhsi...@4ax.com...

Grazie ma mi sa che anche così mi fa continuare l'inserimento da tastiera 
finquando non do invio.

La dichiarazione č:
char longest[MAXLINE];
Lo avrei dovuto dichiarare diversamente? 

 Lo avrei dovuto dichiarare diversamente? 
non ho guardato il resto, ma tieni presente
che i caratteri sono
longest[0],  longest[1], ...., longest[MAXLINE-1]
quindi assegnare qualcosa a longest[MAXLINE]
come fai tu e' un errore grave, perche' stai andando
a memorizzare fuori dall'array....
v.

"vanvera" <van...@acaso.cas> ha scritto nel messaggio 
news:KWW_d.1085204$35.40...@news4.tin.it...

Ti ringrazio di avermi fatto notare quest errore, tuttavia il mio problema è 
diverso, cioè ho un vettore di MAXLINE elemanti (da 0 a MAXLINE-1), lo 
faccio leggere tramite la funzione:
for (i=0;i<MAXLINE-1 || (c=getchar())!=EOF && c!='\n';i++)
     longest[i]=c;
ma l'inserimento da tastiera continua all'infinito cioè non si interrome al 
MAXLINE elemento.

 MAXLINE elemento.
Prima di tutto quel ciclo scritto in quel modo e' concettualmente
errato.
Di fatto l'istruzione getchar viene eseguita una volta sola.
In C se tu scrivi   CONDIZIONE1 || CONDIZIONE2  allora,
se la condizione 1 e' verificata, allora il compilatore sa
gia' che la condizione globale e' vera e quindi LA CONDIZIONE2 NON VIENE
CALCOLATA.
Siccome la condizione i<MAXLINE-1 e' sempre vera fino all'ultimo,
l'istruzione c=getchar() non viene neanche valutata.
(Una cosa analoga avviene per COND1 && COND2 : se COND1 e' falsa allora
certamente COND1&&COND2 e' falsa, e quindi COND2 non viene valutata.)
In generale ti consiglio di evitare "mostri" come quel for().
Non vanno bene per la leggibilita', non hanno nessuna influenza
sull'efficienza, e rischiano come in questo caso di nascondere meglio
degli errori.
Secondo fatto.
sembra di capire che vorresti che l'input da tastiera si interrompa
magicamente dopo che hai letto un certo numero di caratteri,
senza che l'utente prema il tasto "invio" alla fine.
Questo credo non sia possibile. Fino a che non hai premuto
il tasto invio o la combinazione di tasti che segnala la fine
dell'input, i caratteri in qualche modo rimangono in un buffer
(e si possono anche modificare con il tasto Canc o Del) e non
vanno a far parte dello stdin.
Quindi l'ultimo invio e' necessario.
Su certi sistemi (tipo DOS) ci sono funzioni che permettono
di rilevare se e' stato premuto o meno un tasto e che permettono
di fare una cosa simile, ma non credo in modo standard.
ciao,
v.

 
Suggerimento un po' campato per aria da parte di uno che non ha neppure 
provato: con
for (i=0;i<MAXLINE-1 || ( (c=getchar())!=EOF && c!='\n' );i++)
                        ^^^                             ^^^
(notare le parentesi tra le due condizione legate da &&) che ti dice?
-- 
Roberto -MadBob- Guido
mail bob4mail***@***
gmail.com
web 
http://madbob.homelinux.com
BrainTop Project maintainer - 
http://braintop.sf.net

> ma l'inserimento da tastiera continua all'infinito cioč non si interrome 

Ti ringrazio, quali dovrebbero essere listruzioni per leggere nel miglior 
modo possibile un testo 20x80?

 modo possibile un testo 20x80?
prova con fgets() che legge una linea (studiati la sintassi)
alla volta. (NON usare gets(), e' pericoloso)
c'e' forse qualcosa di meglio ma e' molto che
non faccio programmi che chiedono input all'utente da
tastiera. E al momento ho la febbre.
ciao,
v.

"vanvera" <van...@acaso.cas> ha scritto nel messaggio 
news:48Y_d.1085559$35.40...@news4.tin.it...

Mi dispiace per la febbre, ti ringrazio e auguri di una pronta guarigione.
N.B.
Farò cosi come mi hai detto.
Perchè è pericoloso gets()?
Ciao

 Perchè è pericoloso gets()?
perche' gets(char *s) legge nel buffer puntato da s fino a
che non riceve un fine linea.
Se l'utente inserisce per errore o per malizia una linea
piu' lunga di quella che il programmatore aveva previsto
andra' a "sforare" il buffer s e a scrivere in memoria
dove non doveva. (Classico errore usato per "bucare" programmi
e s.o.)
invece fgets(....) permette di specificare una lunghezza massima
della riga da leggere e quindi e' piu' sicura.
v.

"vanvera" <van...@acaso.cas> ha scritto nel messaggio 
news:Js1%d.1086647$35.40...@news4.tin.it...

Grazie ancora.

Non vorrei, rispondendoti, fare la figura di quello che ci è cascato; in 
ogni caso:
partiamo da MAXLINE - 1; non vedo dichiarata la variabile "longest" ma spero 
che tu l'abbia dichiarata, per lo meno, di 10x20 caratteri + il carattere 
terminatore + 9 \n, se vuoi farci almeno stare tutto ciò che ti aspetti.
In ogni caso proviamo a valutare la condizione di termine del ciclo for.
La prima parte
i <MAXLINE-1
farebbe terminare il ciclo un carattere prima dell'ultimo byte dell'array il 
quale, non essendo mai inizializzato e a parte eccezioni, può assumere un 
valore qualsiasi; ma tu, non contento, con
longest[MALINE] = '\0'
fai di più: scrivi fuori dall'array.
Ma lasciamo perdere queste frivolezze, tanto con un debug è difficile 
passarla liscia, e passiamo a valutare la condizione che fà continuare il 
ciclo 'for'. Io non conosco le istruzioni che seguono quel ciclo ma tu, in 
italiano hai scritto:
Ad inizio ciclo, inizializza i a 0 ed incrementala ad ogni ciclo finchè i 
<MAXLINE-1 però, te ne puoi fregare se, acquisendo un carattere e mettendolo 
nella variabile 'c', questo risulta diverso sia da EOF che da \n.
Quindi il tuo ciclo terminerà quando immetterai un EOF (in DOS ^Z, in UNIX 
^D) o un invio (\n) dopo aver digitato almeno 'MAXLINE-1' caratteri (non 
all'infinito).
In ogni caso, con il semplice utilizzo del linguaggio C, non puoi realizzare 
ciò che vorresti ma devi utilizzare delle librerie che, con il variare del 
sistema operativo, a volte non saranno nemmeno simili.
Scusa lo sproloquio e sperando di esserti stato utile...
...un saluto.