C++ : cout ne fonctionne pas...

Résolu/Fermé
lego2 - Modifié par lego2 le 9/07/2011 à 19:32
 lego2 - 9 juil. 2011 à 23:57
Bonjour,

Ce n'est pas pour une erreur d'algorithme que je post mais pour une erreur super (mais alors vraiment) bizare. Voici mon code très simple: il s'agit juste d'une fonction qui remplace dans une chaine de charactère toutes les occurences de d'une sous-chaîne en une autre.

Voici le bug : le cout du main n'affiche rien si le cout de la fin de myFunc est commenté....
par contre si je le commente pas le résultat attendu est le bon.

#include <iostream> 
using namespace std; 
char* myFunc(const char* src, const char* from, const char* to); 

int main() 
{ 
 cout << myFunc("Bonjour","nj","NJ") << endl; //C'EST CETTE LIGNE !!! 
}


La fonction concernée est celle-ci :

#include <vector> 
#include <string.h> 
#include <iostream> 
using namespace std; 
/*  
myFunc : remplace toutes les occurences d'une sous-chaine voulue par une chaine voulue 
retourne la chaine de charactere modifiée 
src : chaine dans lequel est le texte à remplacer 
from : texte à remplacer 
to : texte remplacant 
*/ 
char* myFunc(const char* src, const char* from, const char* to) 
{ 
  vector<char> newString; 
   
  int i = 0; 
  int j = 0; 
   
  while(i < strlen(src)) 
  { 
  if(src[i] == from[0]) { 
    while(src[i] == from[j]) 
    { 
     if(j == strlen(from)-1)//on a trouvé une occurence 
     { 
      for(int k=0; k<strlen(to); k++) 
      { 
       newString.push_back(to[k]); 
      } 
     } 
     
     i++; 
     j++; 
    } 
    j=0; 
   } 
   else 
   { 
    newString.push_back(src[i]); 
    i++; 
   } 
  } 
   
  char dest[newString.size()+1]; 
   
  for(i=0; i<newString.size(); i++) 
  { 
   dest[i]=newString[i]; 
  } 

         cout << "un truc" << endl; //La ligne du main n'affiche rien si je commente celle-ci !! 

  return dest; 
} 


Voilà. Pour info mon débugger est g++ et pour compiller je fais
g++ -c *.cpp #cree les fichers .o
g++ *.cpp -o Executable #compile les fichiers .o en un programme

Je précise que j'ai le message d'avertissement suivant quand je compile (mais à mon avis ça ne vient pas de là):
replace.cpp: In function 'char* myFunc(const char*, const char*, const char*)':
replace.cpp:44: warning: address of local variable 'dest' returned

4 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
9 juil. 2011 à 20:08
Plutôt que d'utiliser des char* et la librairies "string.h" (c'est du C)
Utilises plutôt les atouts du C++, en utilisant std::string dans <string> (sans ".h")

#include <string>

std::string myFunc(
		const std::string &src,
		const std::string &from,
		const std::string &to)
1
Bonjour

Ce que te dit KX marche peut-être, mais ça ne te dit pas pourquoi ce que tu as fait ne marche pas.
C'est expliqué dans le 'warning' du compilateur.
Ta fonction MyFunc Rend un char *, plus précisément l'adresse de début de ton tableau dest.
Mais ton tableau dest est une variable locale à MyFunc. La mémoire correspondante est désallouée quand tu quittes la fonction. Donc quand tu essayes ensuite de faire un cout de ce qu'il y a à cette adresse, ça peut être n'importe quoi. Apparemment, ça tombe des fois sur une chaine vide, des fois sur ce qu'il faut. Mais c'est du hasard. À mon avis, si tu 'bricoles' d'autres lignes dans ta fonction, tu vas avoir des affichages plus ou moins fantaisistes.
1
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
9 juil. 2011 à 20:46
C'est pour ça qu'utiliser des objets, et en particulier std::string permet de passer outre les difficultés liées aux pointeurs... et ça permet d'accéder à des librairies de traitement de chaînes de caractères qui permettent de gagner du temps.

Exemple, en se servant des fonctions de <string>

#include <string> 
#include <iostream> 

std::string myFunc(
		const std::string &src,
		const std::string &from,
		const std::string &to)
{
	std::string res("");
	std::string::size_type begin=0, end;
	while ((end=src.find(from,begin))!=std::string::npos)
	{
		res+=src.substr(begin,end-begin)+to;
		begin=end+from.size();
	}
	return res+src.substr(begin);
}

int main()
{
	std::string res = myFunc("tictactictactictactictac","tic","toc");
	std::cout << res.c_str() << std::endl;
	return 0;
}
1
Merci beaucoup à vous deux, vous m'avez bien aidé :)
J'utilisais des char* car je ne me sens pas très à l'aise avec les string du cpp. En tout cas merci beaucoup pour l'exemple avec les strings, je vais tout de même m'entrainer à les manier un peu.

Du coup j'ai aussi compris pourquoi toutes les fonctions de la lib standard c nécessitaient qu'on leur envoie en parametre la chaine de charactère de destination : c'est parce que si on la crée et la retourne dans la fonction même ça risque d'engendrer des bug si j'ai bien compris. Ca doit être dut au fait que le programme est sensé désallouer la mémoire occupée par les variables locales créées sur le tas à la fin du bloc donc pour les tableaux ça doit pas être facile.

edit : après un peu d'analyse, je tiens à dire bravo pour l'algorithme, il est beaucoup plus court et au final bien plus compréhensible que le mien (c'est l'objectif du C++ par rapport au C à mon avis). Par contre ça se voit que tu as dut pas mal pratiquer les string du c++ car la fonction est vraiment propre.
0