[C con Clase] no puedo usar una funcion mas de 2 veces sino explota el programa

Steven Davidson srd4121 en njit.edu
Dom Mar 13 20:39:32 CET 2011


Hola Jadder,

On 3/13/2011 12:41 AM, Jadder Antonio Moya Urbáez wrote:
> hola a todos tengo un problema, estoy haciendo un programa y tengo
> una funcion pero si esa funcion la utilizo mas de 2 veces me explota
> el programa, y no es una funcion recursiva.
>
> 1-ejecuten el programa y funciona
> 2- descomenten cualquiera de las dos llamada a la funcion o ambas,
> que estan al final del main
>     //conversion(millones);
>     //conversion(miles);
> el programa funciona siempre y cuando dejen solamente 2 fucniones no
> entiendo por que revienta el programa con mas llamada a la misma
> funcion.
>
> aqui les dejo el codigo
>

Te voy comentando a medida que vaya viendo el código fuente.

>
> #include<iostream>
> #include<string.h>

Esto no es correcto. El nombre es <string>.

> #include<cstring>
>
> using namespace std;
> string conversion(string);
>
> main(){

Esto es incorrecto en C++. Deberías escribir:

int main()

>      int longitud =0;
>      char *monto = new char [13];

No entiendo muy bien por qué quieres usar cadenas al estilo de C (char 
*) con cadenas al estilo de C++ (string). Si puedes usar 'string', 
entonces usa objetos de la clase 'string'.

>      string cadena, temporal;
>      string cientos, miles, millones, centavos;
>
>      cout<<  "Digite su monto: ";
>      cin>>  monto;
>      cadena = monto;

Esto es correcto, pero no necesitas 'monto' en este caso, porque podrías 
usar 'cadena' directamente:

cin >> cadena;

>      longitud = strlen(monto);
>

Podrías usar esta función de <cstring> o simplemente usar la función 
miembro, 'size()', de la clase 'string' con el objeto 'cadena'.

Por otro lado, no usas 'cadena' en este programa, por lo que no lo 
necesitas.

>      if(longitud<12){ //creo una cadena temporal rellenando con los
> valores que faltan
>          for(int x=0;x<(12-longitud);x++){
>              temporal+= '0';
>          }

Podrías haber usado la funcionalidad de 'string' para realizar esta 
tarea. Por ejemplo,

temporal += string( 12-longitud, '0' );

Creamos un objeto temporal que contenga varios '0', y lo agregamos al 
final de 'temporal'.

Otra solución es rellenando 'temporal' con los doce '0' y luego copiando 
la cadena en el lugar correcto.

>      }
>      temporal += monto;  //suma la cadena monto a la temporal
>      cout<<  temporal<<  endl;
>
>      //cout<<  monto<<  endl;
>     // cout<<  longitud<<  endl;
>
>      millones = temporal.substr(0,3);
>      miles = temporal.substr(3,3);
>      cientos = temporal.substr(6,3);
>      centavos = temporal.substr(9);
>
>      cout<<  endl;
>      //conversion(millones);
>      //cout<<  "Millones ";
>
>      //conversion(miles);
>      //cout<<  "Mil "<<  endl;
>
>      conversion(cientos);
>      conversion(centavos);
>      cout<<  "Centavos. ";
>
>      cout<<  endl;

Como 'main()' debe retornar un entero, deberías retornar 0 para indicar 
que el programa terminó con éxito.

> }

Ten presente que no liberas la memoria que creaste dinámicanente para 
'monto'.

>
> string conversion(string numero){
>      //cout<<  "aqui: "<<  numero<<  endl;
>      bool c = true;
>      char *cant = new char [4];

Si sabes que son 4 caracteres, entonces crea un array estático:

char cant[4];

>      for(int x=0;x<=2;x++){      //creo este bucle para convertir de
> string a char
>          cant[x] =  numero[x];   // y ponder usar un swithc que trabaja
> con constantes
>      }
>

No es necesario convertir a 'char *'. Puedes acceder a un carácter con 
el operador []. Por ejemplo,

switch( numero[0] )

>      switch(cant[0]){
>          case '9':   cout<<  "Novecientos ";     c=true;    break;
>          case '8':   cout<<  "Ochocientos ";     c=true;    break;
>          case '7':   cout<<  "Setecientos ";     c=true;    break;
>          case '6':   cout<<  "Seiscientos ";     c=true;    break;
>          case '5':   cout<<  "Quinientos ";      c=true;    break;
>          case '4':   cout<<  "Cuatrocientos ";   c=true;    break;
>          case '3':   cout<<  "Trecientos ";      c=true;    break;
>          case '2':   cout<<  "Docientos ";       c=true;    break;
>          case '1':   cout<<  "Ciento ";          c=true;    break;
>          case '0':   cout<<  "";                 c=true;    break;
>          case '.':   cout<<  "con ";             c=true;    break;
>

En lugar de hacer esto, podrías crear un array de constantes y luego 
convierte el carácter-dígito a un entero para que sirva de índice para 
elegir la cadena correcta. Por ejemplo,

centenares[10] = { "", "Ciento", "Doscientos", ... };
...
cout << centenares[ cant[0]-'0' ];

Obviamente, hay que hacer verificar el primer carácter.

>          default:
>          cout<<"defaul1 " ;
>          c=true;    break;

No entiendo muy bien qué quieres hacer con la variable 'c', 
especialmente cuando va a almacenar 'true', irrelevantemente del caso.

>      }
>
>
>      switch(cant[1]){
>          case '9':   cout<<  "Noventa ";         c=true;    break;
>          case '8':   cout<<  "Ochenta ";         c=true;    break;
>          case '7':   cout<<  "Setenta ";         c=true;    break;
>          case '6':   cout<<  "Sesenta ";         c=true;    break;
>          case '5':   cout<<  "Cincuenta ";       c=true;    break;
>          case '4':   cout<<  "Cuarenta ";        c=true;    break;
>          case '3':   cout<<  "Trenta ";          c=true;    break;
>          case '2':   cout<<  "Veinte ";          c=true;    break;
>          case '1':   cout<<  "Novecientos ";     c=true;    break;

Debería ser: "dieci" y luego asociar un número para el otro dígito. Sin 
embargo, hay complicaciones si el número está entre 10 y 15.

>          case '0':   cout<<  "";                 c=true;    break;
>

Hacemos lo mismo que con los centenares

>          default:
>          cout<<"defaul2 " ;
>          c=true;    break;
>      }
>
>      if(c == true){
>          cout<<  "y ";
>          c = false;
>      }
>
>
>      switch(cant[2]){
>          case '9':   cout<<  "Nueve ";           c=true;    break;
>          case '8':   cout<<  "Ocho ";            c=true;    break;
>          case '7':   cout<<  "Siete ";           c=true;    break;
>          case '6':   cout<<  "Seis ";            c=true;    break;
>          case '5':   cout<<  "Cinco ";           c=true;    break;
>          case '4':   cout<<  "Cuatro ";          c=true;    break;
>          case '3':   cout<<  "Tres ";            c=true;    break;
>          case '2':   cout<<  "Dos ";             c=true;    break;
>          case '1':   cout<<  "Uno ";             c=true;    break;
>          case '0':   cout<<  "";                 c=true;    break;
>

Lo mismo que con los centenares y decenas.

>          default:
>                  cout<<"defaul "<<  endl;
>          c=true;    break;
>      }
>      cant = "";
>
> }

Aquí está el error. Esta función retorna un objeto de la clase 'string', 
pero no retornas nada. Esto provoca errores de memoria en tu caso.

Si no quieres retornar una cadena, entonces no lo hagas; define el 
prototipo como:

void conversion( string );

Aunque aconsejo usar referencias a una constante; esto es,

void conversion( const string & );


También ten presente que no liberas la memoria que creaste dinámicanente 
para 'cant'.


Espero que esto te ayude.

Steven





Más información sobre la lista de distribución Cconclase