Newsgroup: it.comp.lang.c
Titolo: Confrontare due stringhe.

Probabilmente questo mio problema per chi usa il c da più di un mese è una
banalità, ma per me che lo uso da poco meno di un mese è un problema
insormontabile.
Allora,  in questi giorni stò sperimentando il C cercando di costruire un
dizionario italiano-inglese, il mio problema è come confrontare due
stringhe, ovvero il semplice (stringa1 == stringa2) non funziona mi dà
sempre come risultato falso anche quando le due stringhe sono diverse.
Come stringhe ho usato due array di caratteri word1[10] , parola1[10] , (il
programma non può memorizzare parole più lunghe di 10 lettere).
Questo è il testo completo del programma (la parte commentata è la critica):
#include <stdio.h>
unsigned int g = 20;
unsigned int i = 0 , carattere=0;
main()
{
  enum continuare {
   si,
   no};
  enum continuare continui;
FILE *archivio;
char parola[10],word[10],tradurre[10],word1[10],parola1[10];
unsigned int x;
char risp[1];
do {
printf("Dammi la parola italiana \n");
scanf("%s",parola);
printf("Dammi di %s la traduzione inglese \n",parola);
scanf("%s",word);
archivio=fopen("/home/lorenzo/Voc.txt","a+");
fprintf(archivio," %s %s\n ",parola,word);
printf("Devi aggiungerne ancora ? (si/no) \n");
scanf("%s",risp);
(risp[0] == 's') ? (continui = si) : (continui = no) ;
}
while (continui == si);
printf("Immetti la parola inglese\n");
scanf("%s",tradurre);
fseek(archivio,0L,SEEK_SET);
do {
fscanf(archivio,"%s %s ",parola1,word1);
if (word1 == tradurre)                                     /* Che il
problema stia nel fatto che ho
usato come stringhe array   di caratteri ?  */
(printf("la traduzione e' %s",parola1)) ;
i=i+1;
}
while (i < g);
fclose(archivio);
}

il confronto tra stringhe in c lo puoi fare con la funzione strcmp.
Devi includere l'header <string.h>

if (word1 == tradurre)                                     
/* Che il problema stia nel fatto che ho usato come stringhe array
di caratteri ?  */
Esatto, ma questo e' l'unico modo per utilizzare le stringhe
(escludendo i puntatori, ma e' lo stesso alla fin fine).
In questo caso il controllo, aggiungendo all'inizio del programma
#include <string.h> si trasforma in 
if (!strcmp(word1, tradurre)) ...


ICQ #34602650


Anche il mio manuale dicedi non usare le variabili globali, ma non spiega il
perchè , che sia dovuto al fatto che queste variabili occupano per tutta la
vita del programma della memoria preziosa? Inoltre c'è un'altra cosa che non
riesco a spiegarmi , e che il mio manuale sconsiglia è l'uso del goto.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/
       Search, Read, Discuss, or Start Your Own    

 riesco a spiegarmi , e che il mio manuale sconsiglia è l'uso del goto.
Perché va contro un'altro dei principi fondamentali: la modularità e
cioè il fatto che ogni blocco di elaborazione deve avere un solo
ingresso ed una sola uscita. Anche in questo caso il vantaggio è di
poter fare più facilmente il debugging indipendente e la manutenzione di
un singolo blocco.
EMG

riesco a spiegarmi , e che il mio manuale sconsiglia è l'uso del goto.
La questione del goto e' veramente vecchia.
Quando e' nata la programmazione strutturata ci si e' resi conto che
tutto cio' che e' possibile fare in modo ripetitivo con l'uso del goto
si puo' anche fare mediante le strutture di controllo fornite dai
linguaggi ad alto livello come il C.
Ricordo che, all'universita', nel mio corso di Programmazione c'erano
delle lezioni pallosissime che si basavano sul riportare codice
scritto mediante goto in formato strutturato.
Sinceramente non ho mai tratto giovamento dal goto (non l'ho mai usato
ne' in pascal, ne' in C) e credo che nel tempo verra' eliminato.

 mailto:
gar...@usa.net
 <
- >ICQ UIN# 23780140 <-

 ne' in pascal, ne' in C) e credo che nel tempo verra' eliminato.
avere dei cicli con più di un'uscita può essere molto comodo a volte (anche
se va contro i principi più ferrei della programmazione strutturata) ma ci
sono molto modi più eleganti di un goto per farlo:
continue, break, return, throw... persino exit(), anche se è un esempio un
po' spinto
se ci pensi bene un goto rompe la visione "continua" che hai di un pezzo di
codice, molto più di quanto non faccia un break o un return
TobiX

codice, molto più di quanto non faccia un break o un return
L'uso del goto non e' affatto necessario ed e' unanimamente
riconosciuto come cattivo stile di programmazione.

 wrote:
[ snip ]
AL>L'uso del goto non e' affatto necessario ed e' unanimamente
AL>riconosciuto come cattivo stile di programmazione.
<Se sei un princiante non continuare a leggere ;)>
Se fosse vero, perche' non lo hanno eliminato ? 8)
Il fatto e' che in alcune occasioni puo' essere utile. Per es. se 
devi uscire contemporaneamente da piu' cicli innestati, il modo piu' 
efficiente e' con un goto.
<fine zona pericolosa ;)>
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

 efficiente e' con un goto.
beh, un caso simile io lo chiamo "eccezione" oppure "fine di
un'elaborazione" e usare un throw o un return č almeno un po' piů elegante
(č sempre scorretto, sia chiaro, solo un po' piů bello, non so se mi spiego)
TobiX

Se fosse vero, perche' non lo hanno eliminato ? 8)
Il problema e' che E' vero.
Non tutto cio' che e' cattivo stile viene eliminato dal linguaggio.
Sergio Polini in un trattato sul "goto" su MCmicrocomputer di qualche
anno fa :
"Quella del goto e' una vecchia storia : si va da chi non ne puo'
proprio fare a meno a chi non ne vuole nemmeno sentire parlare. E'
ormai assodato, nonche' dimostrato, che e' possibile scrivere
qualsiasi tipo di programma senza usare i goto, ma e' anche vero che
questi, sebbene "brutti" informaticamente, sono semplicemente utili e
comodi".
Non discuto l'utilita' di un comando del genere, ma il fatto che esso
e' comunque rimpiazzabile utilizzando i normali controlli C e che si
tende a non usarlo.

 (è sempre scorretto, sia chiaro, solo un po' più bello, non so se mi spiego)
Anche i beati Kernighan e Ritchie suggeriscono delle situazioni in cui
il goto puo' essere accettato.  Leggete la bibbia...
Il goto puo' essere rifiutato per motivi estetici (interruzione del
"flusso naturale"; ma allora i continue, i break ed i return in mezzo
al codice cosa sono?) o perche' genera confusione (ma un "goto error;"
e' assai chiaro) --- sono d'accordo che bisogna usarlo il meno
possibile, ma quando ci vuole ci vuole.
BTW, che c'entrano i throw in un gruppo di C?
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

 (è sempre scorretto, sia chiaro, solo un po' più bello, non so se mi spiego)
Le eccezioni non esistono in C, e comunque sono un argomento a parte.
Quanto al fatto che i return siano più eleganti è tutto da discutere. E'
buona norma di programmazione che le funzioni abbiano (per quanto
possibile) un solo punto di uscita. Il prezzo da pagare è la
manutenibilità del codice, mettere le mani su una funzione scritta da
un'altra persona e disseminata di return diventa un impresa ardua
(supponi per esempio che tu abbia bisogno di introdurre un buffer
allocato dinamicamente, che dovrai distruggere prima di uscire dalla
funzione).


 al codice cosa sono?) 
Non si tratta di questioni estetiche, si tratta di scrivere codice
facilmente manutenibile. I goto rendono semplicemente il codice più
difficile nella manutenzione. Se si ritiene che questo problema sia
minore rispetto all'utilità (nel contesto) dei salti incondizionati, il
problema  naturalmente non sussiste.


 efficiente e' con un goto.
In effetti questo mi sembra sia l'unico caso nel quale il goto è
accettato.
EMG

 wrote:
[ snip ]
EMG>In effetti questo mi sembra sia l'unico caso nel quale il goto è
EMG>accettato.
Hmmm...mi ricordo di un articolo in cui si illustrava l'utilizzo 
dei goto per mantenere un unico punto di uscita dalle funzioni.


Il goto e' sconsigliato poichè utilizzandolo si scrive un codice
"disordinato", un istruzione fatta con il goto puo' sempre essere sostituita
dalle tre strutture fondamentali(cicli,if-else,ecc.)
In realtà ai fini della programmazione cambia poco l'utilizzo del goto, ma
non utilizzandolo risulta piu' ordinato nella stesura.
Almeno io la vedo così...purtroppo non so dirti se ci siano problemi a
livello di codice.
Comunque mi presento;-)))
Mi chiamo roberto, ho 17 anni e studio informatica in un istituto
tecnico...quest'anno utilizziamo il C, e perciò ho pensato di iscrivermi a
questo NG. Sicuramente in caso di bisogno mi saprete rispondere in modo
esauriente!!!!
 Byez By Roby "Offear" '82
 Visit my personal Home-Page:
 
http://surf.to/HPOffear
 And Sign My Guestbook!

Ricordo vagamente che qualche anno fa, in una conferenza Fidonet, si
era discussa la stessa cosa. In effetti io, seguendo l'insegnamento di
alcuni guru e rimanendo fedele ai paradigmi della programmazione
strutturata, ho sempre evitato come la peste l'uso dei goto. Alla
lunga, ho scoperto che, se in un determinato spezzone di codice,
diventa necessario utilizzare un goto per uscirne fuori, vuol dire che
quello spezzone di codice e' stato strutturato male, e che quindi
sarebbe opportuno rivederlo. Oltre tutto, proprio nella conferenza
succitata, ricordo di aver ribattuto proprio con opportune
ristrutturazioni a gente che mi postava codice dicendomi "A si??? e da
qui, come ne esci??"; incredibile a dirsi, il codice
post-ristrutturazione, nella maggior parte dei casi, diventava piu'
semplice e leggibile.....
Ciao!
Luca Menegotto.


 efficiente e' con un goto.
Più efficiente può darsi. Ma è un modo per rendere il codice poco
leggibile e poco manutenibile. Se la funzione è complessa e lavori sul
ciclo più esterno, non sai a priori il comportamento del codice che stai
scrivendo. Il giorno in cui dovrai fare una correzione al programma (o
peggio, qualcun'altro dovrà farla) nella migliore delle ipotesi dovrai
rileggerti tutta la funzione per sapere se la correzione funzionerà,
verrà saltata da un goto o funzionerà solo se una variabile che non
c'entra una mazza perchè si trova in un ciclo nidificato (quindi che
dipende da un altro scope) assume il valore di -32. Questo nella
migliore delle ipotesi, perchè nella peggiore non riesci a prevedere
tutti i possibili comportamenti e introduci un bug.
Torno a dire: si può sempre valutare se i problemi di manutenibilità che
si introducono con i goto sono bilanciati dai vantaggi di efficienza e
comodità di scrittura codice. Ma io sono dell'opinione che in funzioni
complesse lo statement goto è deleterio, una vera e propria mina
vagante.


 dei goto per mantenere un unico punto di uscita dalle funzioni.
Mi sembra veramente un controsenso: per mantenere un unico punto di
uscita renderesti la funzione illegibile e inmanutenibile?
EMG

Mi intrometto: sono un sostenitore del goto!
A mio parere, in certi casi il goto non solo e' utile ma "obbligatorio":
- Gestione delle condizione di errore.
- Macchine a stati  (ovviamente non a tabelle)
- Casi particolari di uscita da loop nidificati non risolvibili con
ristrutturazione.
Ovviamente devono essere imposte delle regole ben precise:
- Uscita da cicli nidificati: le label possono essere inserite solo
all'inizio del ciclo (continue) o immediatamente all'uscita (break)
- Gestione condizioni di errore: unica label di uscita al termine del
blocco, con variabile per il successivo riconoscimento dell'errore
(simulazione del try/catch).
- Macchine a stati: le label possono essere associate solo al punto di
ingresso degli stati, cioe' in corrispondenza dei 'case' (se la macchina a
stati e' implementata con switch).
Non per niente, passando dal C al C++ e Java, il goto e' stato legalizzato
travestendolo.
E' facile criticare un programma Pascal con dei goto quando in C si
riempiono le procedure di break, continue, return.
E facile criticare i goto in un programma C quanto in C+ si puo' usare
try/catch.
E facile criticare i goto in un programma C/C++ quando in Java si possono
usare try/catch e break/continue con label.
Datemi un linguaggio che supporti break/continue con label, return intermedi
e gestione eccezioni (try/catch) e, giuro, nonusero' mai piu' il goto!
Saluti, Alberto.

 e gestione eccezioni (try/catch) e, giuro, nonusero' mai piu' il goto!
Beh, innanzitutto non ci interessa che ci giuri una cosa del genere :-)
Comunque l'abuso delle eccezioni, return, break e via dicendo è
altrettanto deleterio, per cui ti conviene continuare con il goto.



In effetti non sono stato chiaro: non intedevo giustificare l'uso indiscriminato
del goto, ne delle break e continue. Volevo dire che nelle situazioni in cui e'
corretto usare break, continue e try/catch, e' giustificabile l'uso del goto, ma
solo in modo "controllato" tramite linee guida precise e dopo un'attenta
valutazione delle possibili ristrutturazioni applicabili.

stati e' implementata con switch).
Il seguente codice implementa una macchina a stati e non vedo dove
compaia il comando "goto".
Che poi questo comando venga mascherato e il codice seguente tradotto
in l.m. con dei salti e' un altro discorso.
stato = 0 ;
while ( stato <> 99 ) 
{
      switch ( stato ) 
      {
          case 0 : se ( fine input ) stato = 99 
                   altrimenti 
                   {
                     accetta lettera ;
                     stato = 1 ;
                   }
                   break ;
          case 1 : se ( fine input ) stato = 99 
                   altrimenti 
                   {
                     accetta lettera o cifra ;
                     stato = 1 ;
                   }
                   break ;
      }
}

 in l.m. con dei salti e' un altro discorso.
Questa potevi risparmiartela.

> dei goto per mantenere un unico punto di uscita dalle funzioni.
EMG>Mi sembra veramente un controsenso: per mantenere un unico punto di
EMG>uscita renderesti la funzione illegibile e inmanutenibile?
Temo di essere stato poco chiaro: l'idea era quella di sostituire
i 'return' in vari punti della funzione con 'goto exit', e in 
'exit:' liberare le risorse e uscire dalla funzione.
Nulla di cosi' tragico...;)


> riempiono le procedure di break, continue, return.
MS>Usare più vie di uscita (return) per la funzione è una tecnica che
MS>introduce anch'essa grossi problemi di manutenzione.
Infatti e' a questo proposito che io avevo visto consigliare l'uso
(rigorosamente controllato) dei goto (vedi anche altro mio messaggio).
MS>Quanto ai break e ai continue, faccio notare che la questione è alquanto
MS>diversa. Proprio a riguardo dei cicli nidificati: se esci con break tu
MS>sai che da ogni ciclo esci con l'istruzione immediatamente successiva;
MS>se invece usi il goto tu a priori non hai la più pallida idea di dove
MS>finirà il controllo del programma all'uscita del ciclo. 
Questo mi e' poco chiaro: il goto salta all'etichetta corrispondente,
quindi...?
MS>Sai cosa vuol dire questo in fase di manutenzione? Vuol dire rendere 
MS>la vita impossibile a chi deve fare le modifiche (e non bisogna pensare 
MS>solo alla fatica, ma anche ai bug potenziali che si possono introdurre
MS>modificando del codice poco manutenibile).
Hai ragione, ma questo fa parte di un discorso piu' generale: e' 
possibile scrivere programmi semi-incomprensibili anche senza 
usare goto o return multipli. 
Non vorrei passare alla storia ;) come uno strenuo difensore dei 
'goto', che credo di non aver mai usato in un mio programma C.
Pero' non capisco questa 'demonizzazione'...il 'goto' e' 
un'istruzione legale, fa parte del bagaglio di strumenti 
del programmatore C, in rari casi e' utile e rinunciarvi 
per partito preso mi sembra sciocco.


 'goto', che credo di non aver mai usato in un mio programma C.
E io non vorrei passare alla storia come un "untore" del goto :-) In
genere il mio approccio alla programmazione è estremamente pragmatico;
ciò che serve si fa, anche se si chiama goto :-)
