Algo C++ : Aide pour un débutant :)

Algo C++ : Aide pour un débutant :) - C++ - Programmation

Marsh Posté le 26-05-2002 à 10:52:16    

Bonjour,
 
Voilà j'ai écris un algo C++ qui est censé renvoier une chaine de caractère contenant un chiffre romain, d'un chiffre arabe que l'on a précédement entré.  
 
Le tout se passe en mode console.
 
J'aimerais bien testé cet algo mais le problème c'est qu'il plante, et cela depuis que je me sers des chaines de caractères et de la fonction strcat()
 
N'ayant pas encore étudié ce qu'étaient les chaines de caractères en C++, je ne sais pas corriger le problème. Cela dit, je sais qu'il faut se servir quelque part de la fonction malloc() pour les chaines de caractères.
 
Le problème : je n'ai absolument aucune idée quant à a l'utilisation de cette fonction (ou, comment et quand l'utiliser ?)
 
Si quelqu'un pouvait voir cette algo, simplement faire en sorte qu'il ne plante pas en rajoutant au bons endroits les petites choses nécessaires, je lui en serais très reconnaissant ! :)
 
Remarque : je veux juste que l'algo ne plante pas (et donc que l'on me corrige les petites erreurs d'utilisation de char*), je ne demande pas que l'on me corrige/modifie/améliore l'algo de traduction de chiffre arabe en romain, ça je le ferais moi même dès que cet algo fonctionnera :D
 
Un grand Merci !
 
>>>>>>>>>>>>>>>>>>> Algo C ++ sous Visual C++ 6.0
 
#include <iostream.h>
#include <string.h>
 
typedef unsigned int Naturel;  // Nombre entre 0 et 65535
 
 
struct Romain
 
{
 
int millier;   // Caractere representant les milliers : M
int centaine;   // Caractere representant les centaines : C,D    
int dizaine;   // Caractere representant les dizainess : X,L
int unite;    // Caractere representant les unites : I, V
 
};
 
/*  
 
Lettres romaines pour la conversion :
   
 I -- 1
 V -- 5
 X -- 10
 L -- 50
 C -- 100
 D -- 500
 M -- 1000
 
*/
 
//------------------------------------------------
----------------------------
 
 
 
char* multiplie_symbole(int n, char* b)
 
/* Fonction qui recupere un symbole b et renvoie une chaine de caractere constitue de n fois le charactere b */
{
int i;
char* r="";
 
for(i=0;i < n;++i)
 
 {
 r = strcat(r,b);
 }
 
return r;
 
} // fin multiplie_symbole
 
 
//------------------------------------------------
----------------------------
 
char* conversion(Romain n)
 
/* Fonction prenant un Romain n, contenant le nombre de millier, centaine, dizaine et millier du chiffre decompose
 Recuperant les valeurs n.unite, n.dizaine, n.centaine et n.millier dans un tableau en_arabe[]
 Renvoie une chaine de caractere compose des valeurs converties en chiffres romains de chaque valeur de en_arabe[]  
*/
 
{
int i;
char* en_romain[4];
char* symbole[7] = {"I", "V","X","L", "C","D","M"};
int en_arabe[4] = {n.unite, n.dizaine, n.centaine, n.millier};
 
 
 
for(i=0;i<3;++i)
 
{
 
 switch (en_arabe[i])
 
 {
 case(1): {en_romain[i] = symbole[0+i*2];break;}
 
 case(2): {en_romain[i] = multiplie_symbole(2,symbole[0+i*2]); break;}
 
 case(3): {en_romain[i] = multiplie_symbole(3,symbole[0+i*2]);break;}
 
 case(4): {en_romain[i] = strcat(symbole[0+i*2],symbole[1+i*2]);break;}
 
 case(5): {en_romain[i] = symbole[1+i*2];break;}
 
 case(6): {en_romain[i] = strcat(symbole[1+i*2],symbole[+i*2]);break;}
 
 case(7): {en_romain[i] = strcat(symbole[1+i*2],multiplie_symbole(2,symbole[0+i*2]));break;}
 
 case(8): {en_romain[i] = strcat(symbole[1+i*2],multiplie_symbole(3,symbole[0+i*2]));break;}
 
 case(9): {en_romain[i] = strcat(symbole[0+i*2],symbole[3+i*2]);break;}
 
 default: {en_romain[i]= "";break;}
 
 } // fin switch()
 
} // fin for()
 
en_romain[3] = multiplie_symbole(en_arabe[3],symbole[6]); // Pour les milliers il suffit de donner n (ou n = n.miller) fois le symbole M
 
 
 
return strcat(strcat(en_romain[3],en_romain[2]),strcat(en_romain[1],en_romain[0])); // On retourne une seule chaine de caractere faite a partir du tableau contenant tous les bons symboles romains
 
} // fin conversion()
 
 
//------------------------------------------------
----------------------------
 
 
 
Romain decompose(Naturel chiffre)
 
 
/* Fonction qui decompose un nombre entier naturel et retourne le nombre des dizaines, des centaines, des milliers, des unites ect. en entier sous la structure Romain*/
{
 
Romain dec;
 
dec.millier = chiffre / 1000; // Defini combien il y a de millier dans le nombre
 
chiffre = chiffre % 1000;  // On remet le nombre a jour apres avoir calcule le nombre de millier soustrait
 
 
 
dec.centaine = chiffre / 100; // Defini combien il y a de centaine dans le nombre
 
chiffre = chiffre % 100;  // On remet le nombre a jour apres avoir calcule le nombre de centaine soustrait
 
 
 
dec.dizaine = chiffre / 10;  // Defini combien il y a de dizaine dans le nombre
 
chiffre = chiffre % 10;   // On remet le nombre a jour apres avoir calcule le nombre de dizaine soustrait
 
 
 
dec.unite = chiffre;   // A ce moment la le chiffre n'est plus qu'une simple unite de 0 a 9
 
return dec;
 
} // fin decompose()
 
 
//------------------------------------------------
----------------------------
 
 
 
void main()
 
{
Naturel nombre_depart;
Romain nombre_arabe;
char* string;
 
cout<<"Entrez un nombre entier : ";
cin>>nombre_depart;
 
nombre_arabe = decompose(nombre_depart);
 
string = conversion(nombre_arabe);
 
cout<<"En chiffre romain, cela donne : \n"<<string<<endl;
 
}
 
 
 
<<<<<<<<<<<<<<<<<<< Fin

Reply

Marsh Posté le 26-05-2002 à 10:52:16   

Reply

Marsh Posté le 26-05-2002 à 11:11:07    

si t'es en C++, utilise string au lieu de char* c'est plus cohérent!
(enfin si t'as le choix)
 
Et ne parle pas de malloc mais de delete...

 

[jfdsdjhfuetppo]--Message édité par Willyzekid le 26-05-2002 à 11:12:42--[/jfdsdjhfuetppo]


---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 26-05-2002 à 11:13:20    

Aussi sers toi de ton debugger et dis nous où ca plante :D je suis un grand feinéant :)


---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 26-05-2002 à 11:14:34    

Le problème, c'est que tu pense déclarer des tableaux en faisant juste char *tableau. Alors que là, tu définit un pointeur sur un tableau de 0 cases.  
Pour définir un vrai tableau (et donc ne pas avoir d'erreur), il faut, ou bien que tu le déclare en "statique" (char tableau[30]) ou bien en "dynamique"  
(char *tableau = (char*) malloc (30*sizeof(char)) ).
 
Le tableau dynamique est redimensionnable :
 
char *tableau  
 
tableau = (char*) malloc (sizeof(char)); // te donne un tableau d'une case.
 
tableau = (char*) realloc(tableau,2*sizeof(char)); //agrandit le tableau de 1 case (il fait maintenant 2 cases en tout).
 
J'espère que t'auras saisi !  
 
Joel
 
ps : parle pas d'algo en C++, ça veut rien dire. L'algo c'est la manière de penser, le raisonnement pour résoudre un problème mais ce n'est pas attaché à un langage : c'est sensé être appliquable dans tout les langages de programmation.

Reply

Marsh Posté le 26-05-2002 à 13:09:48    

Willyzekid a écrit a écrit :

Et ne parle pas de malloc mais de delete...  




 
 :heink:  
t'es sur que tu confonds pas avec New ?
 
malloc(C) => new(C++)
free(C) => delete(C++)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-05-2002 à 13:18:47    

Harkonnen a écrit a écrit :

 
 
 :heink:  
t'es sur que tu confonds pas avec New ?
 
malloc(C) => new(C++)
free(C) => delete(C++)  




 
oui bon :lol:


---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 26-05-2002 à 14:35:22    

J'ai fait moi-meme ce prog pour convertir les chiffres arabes en romain.
Je l'ai déposé sur cppfrance.com :
http://www.cppfrance.com/article.aspx?Val=674
 
C'est beaucoup plus bourrin ;) mais ca marche.
 
sinon, je regarde ton prog et je vois ce qui va pas..

Reply

Marsh Posté le 28-05-2002 à 19:47:39    

En fait ça plante dès que j'utilise la fonction strcat()
 
...  :cry:

Reply

Marsh Posté le 28-05-2002 à 20:56:06    

Citation :

char* multiplie_symbole(int n, char* b)  
 
/* Fonction qui recupere un symbole b et renvoie une chaine de caractere constitue de n fois le charactere b */  
{  
int i;  
char* r="";
 
for(i=0;i < n;++i)  
 
{  
r = strcat(r,b);
}  
 
return r;  
 
} // fin multiplie_symbole


 

Citation :

The  strcat()  function appends the src string to the dest
string overwriting the `\0' character at the end of  dest,
and  then  adds a terminating `\0' character.  The strings
may not overlap, and the  dest  string  must  have  enough
space for the result
.


C'est pas le cas dans ton exemple.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 29-05-2002 à 08:25:53    

ta regardé mon truc sur www.cppfrance.com ?

Reply

Marsh Posté le 29-05-2002 à 08:25:53   

Reply

Marsh Posté le 29-05-2002 à 08:40:34    

y avais eu un post dans ce genre
http://forum.hardware.fr/forum2.ph [...] h=&subcat=
 
si ca peut aider

Reply

Marsh Posté le 29-05-2002 à 08:55:04    

noops a écrit a écrit :

En fait ça plante dès que j'utilise la fonction strcat()
 
...  :cry:  




 
Je parie 1.52 Euros qu'il fait un coredump !!!


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 29-05-2002 à 09:51:32    

Citation :

char* multiplie_symbole(int n, char* b)
 
/* Fonction qui recupere un symbole b et renvoie une chaine de caractere constitue de n fois le charactere b */
{
int i;
char* r="";
for(i=0;i < n;++i)
 
{
r = strcat(r,b);
}
 
return r;
 
} // fin multiplie_symbole


 
 
Dejà sur cette ligne le compilo devrait te renvoyer un warning, car "" est une literrale de type const char * et non char *. Du coup, le strcat de devrait plus passer (cf post de gilou)...  
 
en fait il faudrait remplacer cette ligne par une allocation dynamique, mais du coup, il te faut liberer par la suite cette memoire allouee...
 
Tu est en C++...
je te conseille d'utiliser auto_ptr (smart pointer) de la STL qui te permettra de t'affranchir de la liberation de la memoire, ou mieux, une string STL...
 
voici des liens sur comme les utiliser...
http://www.roguewave.com/support/d [...] to-ptr.cfm
 
http://www.roguewave.com/support/d [...] string.cfm
 
Les docs proviennent de chez Rogue Wave, auteur de l'implementation de la STL des compilo HP et SUN. Elle est très proche du standard. Tu ne devrait pas avoir trop de difference avec celle fournie par MSVC, tout au moins sur les strings.

Reply

Marsh Posté le 29-05-2002 à 09:52:26    

Voilà un exemple qui fonctionne pas trop mal.

Code :
  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /* I - 1                                                                     */
  4. /* V - 5                                                                     */
  5. /* X - 10                                                                    */
  6. /* L - 50                                                                    */
  7. /* C - 100                                                                   */
  8. /* D - 500                                                                   */
  9. /* M - 1000                                                                  */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. #include <stdio.h>
  13. #define  TAILLE  65+12
  14. char* tab_u[9]={"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
  15. char* tab_d[9]={"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
  16. char* tab_c[9]={"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
  17. int cnv(int nb, char* val);
  18. int main(int nb_parametres, char **parametres)
  19. {
  20. char romain[TAILLE+1]; /* Nombre variant de 0 à 65536 !!! (65*'M') */
  21. int  nombre=0;
  22. int  p=0;
  23. if (nb_parametres > 1)
  24.   {
  25.    p=0;
  26.    while (parametres[1][p] != 0)
  27.     {
  28.      if ( (parametres[1][p] >= '0') && (parametres[1][p] <= '9') )
  29.       {
  30.        nombre=(nombre*10)+parametres[1][p]-'0';
  31.       }
  32.      p++;
  33.     }
  34.   }
  35. cnv(nombre,romain);
  36. fprintf(stdout, "%s.\n", romain);
  37. return 0;
  38. }
  39. int cnv(int nb, char* val)
  40. {
  41. int i=0;
  42. int p=TAILLE;
  43. int z=0;
  44. int l=0;
  45. /* Controle et initialisation */
  46. if (val == NULL) return 0;
  47. for (i=0;i<p;i++) val[i]=' ';
  48. val[p]=0;
  49. if (nb < 1) return 1;
  50. if (nb > 65535) nb=65535;
  51. /* Preparation chaine */
  52. /* unités */
  53. z=nb%10;
  54. if (z > 0)
  55.   {
  56.    l=strlen(tab_u[z-1]);
  57.    p=p-l;
  58.    for (i=0;i<l;i++) val[p+i]=tab_u[z-1][i];
  59.   }
  60. /* dizaines */
  61. nb=(nb-z)/10;
  62. if (nb < 1) return 1;
  63. z=nb%10;
  64. if (z > 0)
  65.   {
  66.    l=strlen(tab_d[z-1]);
  67.    p=p-l;
  68.    for (i=0;i<l;i++) val[p+i]=tab_d[z-1][i];
  69.   }
  70. /* centaines */
  71. nb=(nb-z)/10;
  72. if (nb < 1) return 1;
  73. z=nb%10;
  74. if (z > 0)
  75.   {
  76.    l=strlen(tab_d[z-1]);
  77.    p=p-l;
  78.    for (i=0;i<l;i++) val[p+i]=tab_c[z-1][i];
  79.   }
  80. /* milliers */
  81. nb=(nb-z)/10;
  82. p--;
  83. while ( (nb > 0) && (p >= 0) )
  84.   {
  85.    val[p]='M';
  86.    nb--;
  87.    p--;
  88.   }
  89. return 1;
  90. }


 
Par exemple pour 45 il retourne 'XLV' au lieu de 'VL' mais le résultat est le même !!! (Un romain aurait surment compris)


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 30-05-2002 à 20:10:16    

Yop ! Merci les gars !
 
Je vais tester tout ça ce week end !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed