verificar numeros romanos

Iniciado por m@o_614, 19 Agosto 2013, 19:52 PM

0 Miembros y 1 Visitante están viendo este tema.

m@o_614

Saludos tengo el siguiente programa que me pide que le ingrese un numero romano cualquiera, pero tengo que verificar que si sea romano y que no contenga letras que no sean I, V, X, L, M y es ahi donde tengo el problema

#include <stdio.h>
#include <stdlib.h>
#define TAM 7

int main()
{
    char romano[TAM];
    printf("Dame el primer numero: ");
    fgets(romano,TAM,stdin);
    while(*romano++ != '\0')
    {
        if(*romano!='I','V','X','L','C','M')
            printf("Error!! no es numero romano\n");
    }
    return 0;
}


el error esta en el if

de antemano gracias

amchacon

Ese if no es correcto, no puedes intercalar condiciones con una ,.

Puedes crearte un array con todas las letras del alfabeto romano y recorrerlo.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

fabianjsm


m@o_614

gracias amchacon seria algo como esto???:

#include <stdio.h>
#include <stdlib.h>
#define TAM 7

int main()
{
    char romano[TAM],letras[]={'I','V','X','L','C','M'},*ptr,*p;
    printf("Dame el primer numero: ");
    fgets(romano,TAM,stdin);
    ptr = romano;
    p = letras;
    while(*ptr++ != '\0')
    {
        if(*ptr++ != *p++)
            printf("Error!! no es numero romano\n");
    }
    return 0;
}


y que significa k&r?

eferion

while(*ptr++ != '\0')
    {
        if(*ptr++ != *p++)
            printf("Error!! no es numero romano\n");
    }


Esto está mal... solo te va a funcionar si el caracter introducido es I ( el primero ).

Si metes una X, en cuanto llegue a esta línea la primera vez comparará I con  X y al no ser igual te va a lanzar un mensaje de error.

Tienes que comprobar TODOS los caracteres de 'letras' y si no coincide con ninguno entonces mostrar el mensaje de error.

Otra opción más sencilla podría ser:

if ( strchr( letras, *ptr ) == NULL ) printf("Error!! no es numero romano\n");

amchacon

No, seria un bucle anidado.

Te lo hago con fors que me gustan más:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAM 7

int main()
{
   int i,j;
   char romano[TAM],letras[]={"IVXLCM"};
   printf("Dame el primer numero: ");
   fgets(romano,TAM,stdin);

   for (i = 0; romano[i] != '\n';i++)
   {
       for (j = 0;letras[j];j++)
       {
           if (romano[i] == letras[j]) break;
       }

       if (!letras[j]) { printf("Error! No es un numero romano: %c \n",romano[i],i);}
   }

   return 0;
}
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

Alien-Z

#6
Cuando se inicializan las posiciones de un array de carácteres de este modo hay que añadir manualmente el fin de cadena:

Código (cpp) [Seleccionar]
char romano[TAM],letras[]={'I','V','X','L','C','M'},*ptr,*p; //Este es tu código
char romano[TAM],letras[]={'I','V','X','L','C','M', '\0'},*ptr,*p; //Sería así


Si actualizas la variable de control en la condición del bucle (*ptr++) te estás saltando el primer elemento del array:

Código (cpp) [Seleccionar]
while(*ptr++ != '\0')

Debes de hacerlo antes de terminar el bucle:

Código (cpp) [Seleccionar]
while(*ptr != '\0') {
  ...
  ptr++;
}


Con ese condicional lo único que estás haciendo es comprobando si la entrada es igual a lo que hay en el array "letras[]", no si se trata de un número romano:

Código (cpp) [Seleccionar]
if(*ptr++ != *p++)
              printf("Error!! no es numero romano\n");


Si yo meto "IVXLM" sería correcto pero si introduzco "VII" me la daría por mala cuando si es un número romano.

El ejemplo de amchacon es genial para guiarte en tu código pero me parece que se la ha pasado indicar que solo es para que lo uses como esquema porque no se deben utilizar las instrucciones break/continue para modificar el curso de una iteración en los bucles.

Código (cpp) [Seleccionar]
if (romano[i] == letras[j]) break;

Un saludo.

m@o_614

#7
aqui tengo algunas mejoras que le hice al codigo, aunque cuando le ingreso un numero romano cualquiera como: XVI, me imprime error!no es numero romano y no tengo idea de por que, ya van varias veces que lo checo

#include <stdio.h>
#include <stdlib.h>
#define TAM 7

int main()
{
   int i,j,bandera;
   char romano[TAM],letras[]={'I','V','X','L','C','M','\0'},*ptr,*p;
   printf("Dame el primer numero: ");
   fgets(romano,TAM,stdin);
   ptr = romano;
   p = letras;
   for(i=*ptr;*ptr!='\0';*ptr++)
   {
       bandera = 0;
       for(j=*p;((*p!='\0')&&(bandera==0));*p++)
       {
           if(*ptr == *p)
              bandera = 1;
       }
       if(bandera!=1)
       {
           printf("Error!No es numero romano\n");
           exit(1);
       }
   }
   return 0;
}

amchacon

Cita de: m@o_614 en 20 Agosto 2013, 06:00 AM
aqui tengo algunas mejoras que le hice al codigo, aunque cuando le ingreso un numero romano cualquiera como: XVI, me imprime error!no es numero romano y no tengo idea de por que, ya van varias veces que lo checo
fgets coge también el retorno de carro en la cadena. Por eso puse != '\n en mi código.

Quizás lo más correcto sería:

*ptr != '\n' && *ptr!='\0'

Porque también puede pasar que no coja la cadena entera al ser muy larga, si no coje la cadena entera tampoco cogerá el retorno de carro.

Cita de: Alien-Z en 19 Agosto 2013, 21:58 PMEl ejemplo de amchacon es genial para guiarte en tu código pero me parece que se la ha pasado indicar que solo es para que lo uses como esquema porque no se deben utilizar las instrucciones break/continue para modificar el curso de una iteración en los bucles.
Eso ya depende del profesor, pero break/continue son sentencias totalmente válidas en la vida real.

Generalmente suelen dejar códigos más claros que hacerlas con ellas.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

Alien-Z

#9
Cita de: amchacon en 20 Agosto 2013, 08:10 AMEso ya depende del profesor, pero break/continue son sentencias totalmente válidas en la vida real.

Generalmente suelen dejar códigos más claros que hacerlas con ellas.

Ya veo, no sabía que hubieran otras opiniones respecto a su uso. En mi facultad los profesores nos prohibían estas instrucciones debido a que utilizar un break/continue es equivalante a la instrucción goto: estás "saltando" desde un punto del bucle a otro modificando el curso de ejecución del programa. Teniendo en cuenta que los paradigmas heredan unos de otros: El paradigma orientado a objetos hereda del estructurado que a su vez hereda del secuencial, C++ es OO y Secuencial a la vez, se deben ejecutar las instrucciones sin saltos de línea.

Tú código queda claro porque hay un único break, pero si estuvieramos hablando de una aplicación un poco más compleja en la que, al permitirse el uso de break/continue, cada bucle tuviera 3 o 4, haría casi imposible su comprensión.

Cualquier opinión o debate es bienvenido. Un saludo.