PDA

View Full Version : [C++]Contare gli spazi


Kleidemos
19-05-2003, 07:03
Dovrei contare gli spazi contenuti in una stringa e avrei pensato a questa funz:

int Spazi(string &st)
{
int spazi_cont;
string::iterator it=st.begin();
for( ; it != st.end(); it++)
{
if( st.find(" ") != string::npos )
{
spazi_cont++;
}
if( st.find("\0") != string::npos )
{
break;
}
}
return spazi_cont;
}


Ma mi trova 30000 spazi

ri
19-05-2003, 08:52
int Spazi(string &st)
{
int spazi_cont = 0;
for(int i = 0; i < st.size(); i++)
{
if(st[i] == "")
spazi_cont ++;
}

return spazi_cont;
}


ps: non l'ho testato...

monkey72
19-05-2003, 09:28
Originally posted by "Kleidemos"

Dovrei contare gli spazi contenuti in una stringa e avrei pensato a questa funz:

int Spazi(string &st)
{
int spazi_cont;
string::iterator it=st.begin();
for( ; it != st.end(); it++)
{
if( st.find(" ") != string::npos )
{
spazi_cont++;
}
if( st.find("\0") != string::npos )
{
break;
}
}
return spazi_cont;
}


Ma mi trova 30000 spazi

una curiosità... ma l'iteratore string::iterator che hai usato ti dovrebbe permettere la scansione dei caratteri x come lo hai usato tu... premesso che non l'ho mai usato mi sembra di averne visto da qualche parte un uso di enumerazione di stringhe contenute in un vettore...
ripeto non entro nel merito, è solo una curiosità, vorrei capire meglio :)

/\/\@®¢Ø
19-05-2003, 10:21
Non e' molto piu' semplice qualcosa del genere (non testato) ?

int Spazi(const string& st)
{
int result=0;
for ( string::const_iterator i=st.begin(); i != st.end(); ++i )
{
if ( *i == ' ' )
++result;
}
return result;
}


In ogni caso nel ciclo for non dovresti usare string::npos ma st.end() (ed e' per quello che ti da un risultato sballato)

Edit: ops, mi sono accorto che e' praticamente identico al codice di ri (a parte il " " corretto in ' ' :p :D)

/\/\@®¢Ø
19-05-2003, 10:27
Originally posted by "monkey72"



una curiosità... ma l'iteratore string::iterator che hai usato ti dovrebbe permettere la scansione dei caratteri x come lo hai usato tu... premesso che non l'ho mai usato mi sembra di averne visto da qualche parte un uso di enumerazione di stringhe contenute in un vettore...
ripeto non entro nel merito, è solo una curiosità, vorrei capire meglio :)
Molto probabilmente string::iterator non e' altro che un altro nome per char*, e quindi usare uno o l'altro non dovrebbe far differenza.

monkey72
19-05-2003, 10:42
Originally posted by "/\/\@®¢Ø"


In ogni caso nel ciclo for non dovresti usare string::npos ma st.end() (ed e' per quello che ti da un risultato sballato)



xchè? lui sta testando se il carattere corrente è blank, xchè deve controllare che sia finita la stringa?... semmai nel secondo if, ma a che pro, xche string::npos gli fa sballare il risultato?

monkey72
19-05-2003, 10:46
p.s. marco secondo me sono giuste sia la tua soluzione che quella di ri, sono semplici ma efficaci, ma volevo capire xchè sballa quella di kleidemos ;)

ri
19-05-2003, 12:11
perchè npos è una costante che rappresenta la lunghezza massima di una stringa
l'algoritmo find invece, in caso di "non trovato", restituisce l'end dell'oggetto

prova a fare una stampa di string::npos e vediamo se ti esce 30000 :)

/\/\@®¢Ø
19-05-2003, 12:15
Originally posted by "monkey72"



xchè? lui sta testando se il carattere corrente è blank, xchè deve controllare che sia finita la stringa?... semmai nel secondo if, ma a che pro, xche string::npos gli fa sballare il risultato?


porc... :mad: stamattina dormo della grossa ! :muro: :muro:.
Kleidemos, l'errore sta nel fatto che mescoli due modi di operare: da un lato fai la scansione 'manuale' della stringa col ciclo for (ma l'iteratore non lo utilizzi mai!), dall'altro utilizzi il metodo find che fa la scansione di suo: il metodo find cerca tutta la stringa e quindi e' inutile iterare. Il secondo find e' ancora piu' pericoloso: a differenza dei char* non e' necessariamente detto che le string finiscano con un '\0'. Se questo capita (come ad esempio nel gcc) in ogni caso il ciclo termina al primo passaggio perche' il '\0' viene trovato alla fine della stringa.
La soluzione e' quindi:
1- iteri
2- usi find

nel primo caso va bene il codice che ti e' gia' stato mostrato
nel secondo puoi fare cosi'

int Spazi(const string &st)
{
int spazi_cont=0;
string::size_type pos = st.find_first_of( ' ' );
while( pos != string::npos )
{
spazi_cont++;
pos = st.find_first_of( ' ' , pos+1 );
}
return spazi_cont;
}

(ho usato find_first_of invece che find visto che dovevo cercare un solo carattere, ma anche find sulla strigna andava bene cmq)
Pero' mi sembra una fatica inutile rispetto l'entita' del compito.

ri
19-05-2003, 12:15
:confused:
ho appena controllato quanto vale quel const e mi da -1...
:confused:

/\/\@®¢Ø
19-05-2003, 12:16
dimenticavo...
spazi_cont va inizializzato a zero ! ;)

monkey72
19-05-2003, 12:20
io sapevo che s.find(c) cerca la prima occorrenza del carattere c nella stringa s e che ritorna un valore intero senza segno che è la posizione di c se c'è, altrimenti ritorna una costante predefinita che è string::npos "non posizione" che vale -1

monkey72
19-05-2003, 12:22
Originally posted by "ri"

:confused:
ho appena controllato quanto vale quel const e mi da -1...
:confused:

appunto.... :) ;)

monkey72
19-05-2003, 12:32
Originally posted by "/\/\@®¢Ø"





int Spazi(const string &st)
{
int spazi_cont=0;
string::size_type pos = st.find_first_of( ' ' );
while( pos != string::npos )
{
spazi_cont++;
pos = st.find_first_of( ' ' , pos+1 );
}
return spazi_cont;
}



non ho più obiezioni ;) :)