Hola amigos, me he creado una aplicacion que le introduces un numero entre 0 y 999999 y lo convierte en una cadena de texto. La verdad es que la parte que lo pasa a texto me he liado y he acabado haciendo todo con switch y condicionales y me gustaria ver como simplificarlo para no usar tantos. Aqui el codigo:
Código PHP:
#include <iostream.h>
#include <limits>
#define LIMITE_SUP 999999.99
#define LIMITE_INF 0
#define N_DIGITOS_ENTERO 6
#define UNIDADES 5
#define DECENAS 4
#define CENTENAS 3
#define MILLARES 2
#define DECENAS_MILLAR 1
#define CENTENAS_MILLAR 0
using namespace std;
void pausar()
{
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.get();
}
double SolicitarNumero(void)
{
double num;
//Pido un valor dentro del rango valido
do{
cout << "Introduce un numero (" << LIMITE_INF << " a " << LIMITE_SUP << "): ";
cin >> num;
if(num < LIMITE_INF || num >= LIMITE_SUP)
cout << "El numero introducido excede del rango valido. Vuelva a intentarlo." << endl;
}while(num < LIMITE_INF || num >= LIMITE_SUP);
return num;
}
string ObtenerString(double num, int digitos[N_DIGITOS_ENTERO])
{
//Cadenas constantes
char cadenas[4][11][15]={{"","mil ","dosmil ","tresmil ","cuatromil ","cincomil ","seismil ","sietemil ","ochomil ","nuevemil "},
{"","cien ","doscientos ","trescientos ","cuatrocientos ","quinientos ","seiscientos ","setecientos ","ochocientos ","novecientos "},
{"","diez ","veinte ","treinta ","cuarenta ","cincuenta ","sesenta ","setenta ","ochenta ","noventa "},
{"cero","uno","dos","tres","cuatro","cinco","seis","siete","ocho","nueve"}};
char cadenaDecenas[9][15]={"once","doce","trece","catorce","quince","dieciseis","diecisiete","dieciocho","diecinueve"};
string salida;
bool termina=false;
for(int i=0; i<N_DIGITOS_ENTERO && !termina; i++){
bool compuesta=false;
switch(digitos[i]){
case 0: //Si es un cero no hacemos nada excepto que sea la unidad y el resto de posiciones tambien sea cero
if(i==N_DIGITOS_ENTERO-1){
for(int j=0;j<N_DIGITOS_ENTERO;j++){ //Busco para saber si hay algun digito diferente de 0
if(digitos[j] != 0){
compuesta=true;
break;
}
}
if(!compuesta) //Si no hay ningun digito diferente de 0 coloco 'cero' en la cadena de salida
salida += cadenas[i][digitos[i]];
}
break;
default: //Si no es cero el digito
for(int j=i+1;j<N_DIGITOS_ENTERO;j++){ //Busco si despues de dicho digito hay algun digito diferente de 0
if(digitos[j] != 0){
compuesta=true;
break;
}
}
if(compuesta){ //Si existe algun digito diferente de 0 detras de en el que estoy ahora...
switch(i){
case UNIDADES:
salida += cadenas[i][digitos[i]]; //Inserto la cadena correspondiente
break;
case DECENAS: case DECENAS_MILLAR: //Si la decena es 2 uso la cadena "veinti" para crear una cadena compuesta
switch(digitos[i]){
case 1: //Si es 1 uso las cadenas oportunas para las decenas compuestas
salida += cadenaDecenas[digitos[i+1]-1];
if(i==DECENAS){
termina=true;
}else if(i==DECENAS_MILLAR){
salida += cadenas[0][digitos[1]];
i++;
}
break;
case 2: //Si es 2 uso la cadena oportuna para las veintenas compuestas
salida += "veinti";
break;
default:
if(i==DECENAS_MILLAR)
salida += cadenas[2][digitos[i]];
else
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
if(i==DECENAS || i==DECENAS_MILLAR) //Si es las decenas coloco la cadena "y "
salida += "y ";
}
break;
case CENTENAS: //Si es 1 y no son las unidades cojo del segundo array de cadenas para crear una cadena compuesta
if(digitos[i]==1)
salida += "ciento ";
else
salida += cadenas[i-2][digitos[i]]; //Inserto la cadena correspondiente
break;
case MILLARES:
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
salida += " ";
salida += cadenas[0][1];
break;
case CENTENAS_MILLAR:
if(digitos[i]==1){
salida += "ciento ";
}else{
salida += cadenas[3][digitos[i]];
salida += "cientos "; //Inserto la cadena correspondiente
}
break;
default: //Para cualquier otro valor
salida += cadenas[i][digitos[i]]; //Inserto la cadena correspondiente
}
}else{ //Si no existe ningun digito diferente de 0 detras del actual
switch(i){
case UNIDADES:
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
break;
case DECENAS:
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
break;
case CENTENAS:
salida += cadenas[1][digitos[i]]; //Inserto la cadena correspondiente
break;
case DECENAS_MILLAR:
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
salida += cadenas[0][1];
break;
case CENTENAS_MILLAR:
salida += cadenas[1][digitos[i]]; //Inserto la cadena correspondiente
salida += cadenas[0][1];
break;
case MILLARES:
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
salida += " ";
salida += cadenas[0][1]; //Inserto la cadena que le corresponda
}
}
}
}
return salida;
}
void SepararDigitos(int num, int digitos[N_DIGITOS_ENTERO])
{
for(int i=N_DIGITOS_ENTERO-1; i>=0; i--,num /=10)
digitos[i]=num%10;
}
int main(int argc, char* argv[])
{
int parteEntera,parteDecimal;
double num;
string salida;
int digitos[N_DIGITOS_ENTERO];
num=SolicitarNumero();
//Separo la parte entera y la parte decimal truncando la decimal y quedandome solo con dos decimales
parteEntera = num;
parteDecimal = (num-parteEntera)*100;
//Separo los digitos enteros
SepararDigitos(parteEntera,digitos);
//Concateno la cadena a partir de sus digitos
salida=ObtenerString(num,digitos);
//En caso de añadir una parte a la cadena la cual tiene un espacio detras y luego no añadir nada despues
//nos dejaria con una cadena terminada con un espacio asi que solo añado un espacio cuando esta no acabe
//ya en espacio
if(salida[salida.length()-1]!= ' ')
salida += " ";
//Añado la cadena de la parte decimal
cout << salida << parteDecimal << "/100"<< endl;
cout << "Pulsa intro para salir...";
pausar();
return 0;
}
//---------------------------------------------------------------------------
Otra cosa ¿como hago para que cuando solicito el numero no me muestre el limite superior en notacion cientifica? quiero que lo muestre tal cual lo tengo definido pero no doy con la forma.
Y un ultimo fallo que tiene el codigo es que si meto 999999.99 me muestra "novecientos noventa y nueve mil novecientos noventa y nueve y 98/100" deveria mostrar "novecientos noventa y nueve mil novecientos noventa y nueve y 99/100" ¿porque le resta uno a la parte decimal al extraerlo? ¿como corrijo eso?