OVH Cloud OVH Cloud

string, references, modification

8 réponses
Avatar
Nicolas Aunai
salut,

j'ai un petit probleme lorsque je tente de remplir une variable de type
string et je ne comprends pas pourquoi cela ne fonctionne pas...

voici le code exemple :

#include <iostream>
#include <string>

using namespace std;

void f(string &mot)
{
cout<<"tape un mot"<<endl;
cin>>mot;
cout<<"mot de la fonction : "<<mot<<endl;

}

void recopie(string &a,string &b)
{
for(unsigned int i=0;i<a.length();i++)
{
if(a[i]=='a')
b[i]='_';
else
b[i]='.';
}
}

int main()
{

string mon_mot;
string mot2;
f(mon_mot);
cout<<"mot du main: "<<mon_mot<<endl;
recopie(mon_mot,mot2);

cout<<"mon_mot : "<<mon_mot<<" mot2 :"<<mot2;
return 0;
}

--
Nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@hotmail.com

8 réponses

Avatar
Benoit Rousseau
Nicolas Aunai wrote:
salut,


void recopie(string &a,string &b) {


etant donné que tu ne comptes pas modifier a, tu peux le garantir par
void recopie(const string& a, string &b)

for(unsigned int i=0;i<a.length();i++)
{
if(a[i]=='a')
b[i]='_';
else
b[i]='.';
}
}


Au début de la fonction, b est de taille nulle.
Tu peux faire
b.resize( a.length() );
pour le redimentionner.

void recopie(string &a,string &b) {
b.resize( a.length() );
for(unsigned int i=0;i<a.length();i++) {
if(a[i]=='a') b[i]='_';
else b[i]='.';
}
}

--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/

Avatar
kanze
Nicolas Aunai ç wrote in message
news:...

j'ai un petit probleme lorsque je tente de remplir une variable de
type string et je ne comprends pas pourquoi cela ne fonctionne pas...

voici le code exemple :

#include <iostream>
#include <string>

using namespace std;

void f(string &mot)
{
cout<<"tape un mot"<<endl;
cin>>mot;
cout<<"mot de la fonction : "<<mot<<endl;

}



Tu as oublié une ligne essentielle de la fonction suivante :

void recopie(string &a,string &b)
{


assert( b.size() >= a.size() ) ;

C'est une précondition essentielle. Un commentaire de cet effet serait
aussi une bonne chose.

for(unsigned int i=0;i<a.length();i++)
{
if(a[i]=='a')
b[i]='_';
else
b[i]='.';
}
}

int main()
{

string mon_mot;
string mot2;
f(mon_mot);
cout<<"mot du main: "<<mon_mot<<endl;


Et ici, il y a une violation de la précondition (probablement), puisque
mot2.size() est 0.

recopie(mon_mot,mot2);

cout<<"mon_mot : "<<mon_mot<<" mot2 :"<<mot2;
return 0;
}


Probablement, tu ne voulais pas la précondition, mais plutôt que le
texte vient remplacer ce qu'il y avait avant. Dans ce cas-là, il
faudrait :

struct Mapper
{
char operator()( char ch )
{
return ch == 'a' ? '_' : '.' ;
}
}

void
recopie( std::string const& source, std::string& dest )
{
source.clear()
std::transform( source.begin(), source.end(),
std::back_inserter( dest ),
Mapper() ) ;
}

ou si tu tiens à la boucle explicite :

void
recopie( std::string const& source, std::string& dest )
{
source.clear() ;
for ( std::string::const_iterator iter = source.begin() ;
iter != source.end() ;
++ iter ) {
dest.push_back( *source == 'a' ? '_' : '.' ) ;
}
}

En général, en revanche, je crois qu'on préfèrerais la solution où la
fonction renvoie le résultat de la transformation, c-à-d (avec Mapper,
ci-dessus) :

std::string
recopie( std::string const& source )
{
std::string result ;
std::transform( source.begin(), source.end(),
std::back_inserter( result ),
Mapper() ) ;
return result ;
}

Sauf qu'évidemment, le nom ne convient pas. (Il ne convenait pas avant,
non plus.)

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Nicolas Aunai
"" a dit :


... tout un tas de trucs que j'ai pas compris... c'était fait exprès ?
:(

--
Nico,
http://astrosurf.com/nicoastro
messenger :
Avatar
Fabien LE LEZ
On Wed, 19 Nov 2003 18:44:22 +0100, Nicolas Aunai
ç wrote:

... tout un tas de trucs que j'ai pas compris... c'était fait exprès ?


Non. James t'a montré quelques techniques très utilisées en C++ ; je
te conseille donc de les regarder de près. (Le principe n'est pas très
compliqué, mais c'est vrai que les écritures paraissent souvent
lourdes, ce qui a tendance à faire peur quand on voit ce genre de
bestioles pour la première fois).

--
;-)

Avatar
Nicolas Aunai

... tout un tas de trucs que j'ai pas compris... c'était fait exprès ?


Non. James t'a montré quelques techniques très utilisées en C++ ; je
te conseille donc de les regarder de près. (Le principe n'est pas très
compliqué, mais c'est vrai que les écritures paraissent souvent
lourdes, ce qui a tendance à faire peur quand on voit ce genre de
bestioles pour la première fois).


le problème c'est que je raisonne encore à la C, je connais 0,0000002%
de la STL, donc ça, ça ressemble a du chinois..

y'aurait-il un *bon* site, document pdf, etc... qui documenterai bien
la STL ? par exemple j'utilise un peu string, mais je ne sais même pas
les méthodes que je peux utiliser etc...

--
Nico,
http://astrosurf.com/nicoastro
messenger :


Avatar
tib.motuelle
Nicolas Aunai ç wrote in message news:...
y'aurait-il un *bon* site, document pdf, etc... qui documenterai bien
la STL ? par exemple j'utilise un peu string, mais je ne sais même pas
les méthodes que je peux utiliser etc...


Celui-ci est très bien (documentation de toute la lib standard):
http://www.dinkumware.com/refxcpp.html

Bertrand.

Avatar
kanze
Fabien LE LEZ wrote in message
news:...
On Wed, 19 Nov 2003 18:44:22 +0100, Nicolas Aunai
ç wrote:

... tout un tas de trucs que j'ai pas compris... c'était fait exprès ?


Non. James t'a montré quelques techniques très utilisées en C++ ;


Ben, je ne sais pas ce qu'il n'a pas compris, mais la chose essentielle
que j'ai dit n'a rien à voir avec le langage utilisé : si on ne définit
pas exactement ce que doit faire une fonction, il y a peu de chances 1)
qu'elle le fasse correctement, et 2) que la reste du programme l'utilise
correctement. Le début de son problème, c'est qu'il n'a pas bien défini
ce que fait « recopie », et que donc, il s'est mal servi par la suite.

Mais c'est vrai que j'ai melangé deux aspects, qu'il aurait mieux fait
garder séparé (même si tout les deux sont importants). Il y a l'aspect
génie logiciel : quelles sont les préconditions de sa fonction ? La
plupart des réponses semblaient accepter que la fonction était correcte,
et donc ont corrigé l'appel -- d'après mon expérience, je pense plutôt
que l'erreur était dans la fonction, et non à l'appel. sans savoir ce
que doit faire exactement la fonction, c'est impossible à trancher, mais
en général, je trouve qu'imposer des préconditions du genre dest.size()
= source.size() n'est pas une bonne conception. (De même qu'appeler une
fonction « recopie » quand en fait elle fait une transformation radicale

n'est pas une bonne idée non plus.)

L'autre aspect, évidemment, c'est le fait que le C++ a déjà des
fonctions toutes faites et des idiomes propre pour ce genre de chose. Et
qu'il vaut mieux les apprendre et les utiliser. Sa fonction « recopie »
existe déjà dans la bibliothèque standard -- où elle s'appelle
« transform ». Évidemment, dans la bibliothèque, elle est présente dans
une forme plus générique. Mais pour l'utiliser, il suffit de fournir la
définition de la transformation voulue. Et évidemment, l'utilisation des
back_inserter pour que la sortie vient s'ajouter à la chaîne, plutôt que
remplacer les caractères existants (qu'il n'y avait pas), c'est l'idiome
standard, quoi.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
James Kanze
(Bertrand Motuelle) writes:

|> Nicolas Aunai ç wrote in message
|> news:...
|> > y'aurait-il un *bon* site, document pdf, etc... qui documenterai
|> > bien la STL ? par exemple j'utilise un peu string, mais je ne sais
|> > même pas les méthodes que je peux utiliser etc...

|> Celui-ci est très bien (documentation de toute la lib standard):
|> http://www.dinkumware.com/refxcpp.html

C'est un très bonne documentation de référence, mais son but
n'est pas tutoriel. La site SGI serait peut-être mieux, mais surtout
le livre de Matt Austern.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93