Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: m@o_614 en 5 Abril 2014, 02:17 am



Título: validar numeros
Publicado por: m@o_614 en 5 Abril 2014, 02:17 am
Saludos, tengo el siguiente segmento de codigo dentro de un CASE '[' o
CASE INDEXADO_INDIRECTO, donde tengo que validar una cadena esta cadena que inicia con [, debe de tener o bien una D despues del corchete o un numero en base DECIMAL (tiene un rango especifico de valores para que sea valido)seguido por una , despues un registro que puede ser x,y,sp,pc  y por ultimo un corchete de cierre ]

por ejemplo si tengo:

[5,Sp -> error: le falta el ultimo corchete
[,x] -> no puede haber una instruccion vacia antes de la coma
[100,] ->no puede haber una instruccion vacia despues de la coma
[ ->despues del primer [ debe haber dos registros separados por una , y despues ]
[AD,sp]-> el primer registro tiene que ser la letra D

PERO cuando le pongo algo como:

[5A9,x] -> aqui me aparece que es un numero valido, pero para este caso en especial solo puede aceptar numeros decimales, y no se como corregir esto

Código
  1. case INDEXADO_INDIRECTO:
  2.            i = 1;
  3.            tam = strlen(operando);
  4.            car = operando[i++];
  5.            if(car == '\0')
  6.               printf("Despues del primer [ debe haber dos registros separados por , y un corchete de cierre\n");
  7.            else
  8.            {
  9.                if(operando[tam-1] != ']')
  10.                   printf("Error: No se encontro corchete de cierre\n");
  11.                else
  12.                {
  13.                    switch(car)
  14.                    {
  15.                        case ']':
  16.                           printf("No pueden estar los corchetes vacios\n");
  17.                           break;
  18.                        case ',':
  19.                           printf("No puede haber una instruccion vacia antes de la coma\n");
  20.                           registro = obtenerRegistro(operando);
  21.                           if((strcmp(registro,"\0")) == 0)
  22.                              printf("No puede haber una instruccion vacia despues de la coma\n");
  23.                              break;
  24.                        case '0':
  25.                        case '1':
  26.                        case '2':
  27.                        case '3':
  28.                        case '4':
  29.                        case '5':
  30.                        case '6':
  31.                        case '7':
  32.                        case '8':
  33.                        case '9':
  34.                           if((ptr = strchr(operando,',')) == 0)
  35.                              printf("Despues del primer corchete debe haber dos registros separados por una ,\n");
  36.                           else
  37.                           {
  38.                               base = 10;
  39.                               x = 1;
  40.                               k = 0;
  41.                               esIndexadoIndirecto16bits = 1;
  42.                               instruccion = obtenerInstruccion(operando,x);
  43.                               numero = obtenerNumero(instruccion,k,base);
  44.                               registro = obtenerRegistro(operando);
  45.                               registro = convertirMayusculas(registro);
  46.                               if((strcmp(registro,"\0")) == 0)
  47.                                  printf("No puede haber una instruccion vacia despues de la coma\n");
  48.                               else
  49.                               {
  50.                                   if(!verificarRegistro(registro))
  51.                                   {
  52.                                       esIndexadoIndirecto16bits = 0;
  53.                                       printf("Los registros validos de un direccionamiento Indexado indirecto de 16 bits son X,Y,SP,PC\n");
  54.                                   }
  55.                                   if(!verificarRangoIndexadoIndirecto(numero))
  56.                                   {
  57.                                       esIndexadoIndirecto16bits = 0;
  58.                                       printf("El rango valido de un direccionamiento Indexado Indirecto de 16 bits es de 0 a 65535\n");
  59.                                   }
  60.                                   if(esIndexadoIndirecto16bits)
  61.                                   {
  62.                                       if((indice = buscarDireccionamiento(encontrado,direccionamiento[7]))!= -1)
  63.                                          printf("Indexado Indirecto de 16 bits([IDX2]), de %s bytes\n",encontrado->total_bytes[indice]);
  64.                                       else
  65.                                          printf("el codop %s no acepta el direccionamiento indexado indirecto de 16 bits\n",encontrado->instruccion);
  66.                                   }
  67.                               }
  68.                           }
  69.                          break;
  70.                       case '-':
  71.                          if((ptr = strchr(operando,',')) == 0)
  72.                             printf("Despues del primer corchete debe haber dos registros separados por una ,\n");
  73.                          else
  74.                          {
  75.                              base = 10;
  76.                              x = 0;
  77.                              k = 1;
  78.                              esIndexadoIndirecto16bits = 1;
  79.                              instruccion = obtenerInstruccion(operando,x);
  80.                              numero = obtenerNumero(instruccion,k,base);
  81.                              registro = obtenerRegistro(operando);
  82.                              registro = convertirMayusculas(registro);
  83.                              if((strcmp(registro,"\0")) == 0)
  84.                                 printf("No puede haber una instruccion vacia despues de la coma\n");
  85.                              else
  86.                              {
  87.                                  if(!verificarRegistro(registro))
  88.                                  {
  89.                                      esIndexadoIndirecto16bits = 0;
  90.                                      printf("Los registros validos de un direccionamiento Indexado indirecto de 16 bits son X,Y,SP,PC\n");
  91.                                  }
  92.                                  if(!verificarRangoIndexadoIndirecto(numero))
  93.                                  {
  94.                                      esIndexadoIndirecto16bits = 0;
  95.                                      printf("El rango valido de un direccionamiento Indexado Indirecto de 16 bits es de 0 a 65535\n");
  96.                                  }
  97.                                  if(esIndexadoIndirecto16bits)
  98.                                  {
  99.                                      if((indice = buscarDireccionamiento(encontrado,direccionamiento[7]))!= -1)
  100.                                         printf("Indexado Indirecto de 16 bits([IDX2]), de %s bytes\n",encontrado->total_bytes[indice]);
  101.                                      else
  102.                                         printf("el codop %s no acepta el direccionamiento indexado indirecto de 16 bits\n",encontrado->instruccion);
  103.                                  }
  104.                              }
  105.                          }
  106.                          break;
  107.                       default:
  108.                          x = 1;
  109.                          esIndexadoIndirecto_Acumulador = 1;
  110.                          instruccion = obtenerInstruccion(operando,x);
  111.                          registro = obtenerRegistro(operando);
  112.                          registro = convertirMayusculas(registro);
  113.                          if(!indirectoAcumulador_D(instruccion))
  114.                          {
  115.                              printf("Error: El Acumulador valido de un Indexdo Indirecto de acumulador es D\n");
  116.                              esIndexadoIndirecto_Acumulador = 0;
  117.                          }
  118.                          if(!verificarRegistro(registro))
  119.                          {
  120.                              printf("Los registros validos de un Indexado Indirecto de Acumulador son X,Y,SP,PC\n");
  121.                              esIndexadoIndirecto_Acumulador = 0;
  122.                          }
  123.                          if(esIndexadoIndirecto_Acumulador)
  124.                          {
  125.                              if((indice = buscarDireccionamiento(encontrado,direccionamiento[6]))!= -1)
  126.                                 printf("Indexado Indirecto de Acumulador D,([D,IDX]), de %s bytes\n",encontrado->total_bytes[indice]);
  127.                              else
  128.                                 printf("el codop %s no acepta el direccionamiento indexado indirecto de acumulador D\n",encontrado->instruccion);
  129.                          }
  130.                      }
  131.                }
  132.            }
  133.            break;
  134.  

y las demas funciones son estas, no puse todo el codigo porque son como 1700 lineas de codigo,se que tengo algunas malas practicas de programacion pero ahora lo importante es corregir ese bug.

Código
  1. char *obtenerRegistro(char *operando)
  2. {
  3.    int j,i = 0;
  4.    char *cadena = NULL,c[2];
  5.    cadena = calloc(2,sizeof(char));
  6.    while(operando[i] != ',')
  7.       i++;
  8.    for(j = i+1;operando[j] != ']';j++)
  9.    {
  10.        sprintf(c,"%c",operando[j]);
  11.        strcat(cadena,c);
  12.    }
  13.    return cadena;
  14. }
  15. char *obtenerInstruccion(char *operando,int x)
  16. {
  17.    int i;
  18.    char *cadena = NULL,c[2],signo[] = {'\0',','};
  19.    cadena = calloc(7,sizeof(char));
  20.    for(i = x;operando[i] != ',';i++)
  21.    {
  22.        sprintf(c,"%c",operando[i]);
  23.        strcat(cadena,c);
  24.    }
  25.    return cadena;
  26. }
  27.  
  28. int obtenerNumero(char *operando,int x,int base)
  29. {
  30.    int i,potencia,num_decimal = 0,lon,entero = 0;
  31.    lon = strlen(operando);
  32.    for(i = lon-1,potencia = 1;i >= x;i--,potencia*=base)
  33.    {
  34.        if(esLetraBase16(operando[i]))
  35.           entero = hexadecimal(operando[i]);
  36.        else
  37.           entero = operando[i]-'0';
  38.        num_decimal+= potencia*entero;
  39.    }
  40.    if(operando[CERO] == '-')
  41.       num_decimal*= -1;
  42.    return num_decimal;
  43. }
  44.  
  45. int hexadecimal(char caracter)
  46. {
  47.    int decimal;
  48.    switch(caracter)
  49.    {
  50.        case 'A':case 'a':
  51.           decimal = 10;
  52.           break;
  53.        case 'B':case 'b':
  54.           decimal = 11;
  55.           break;
  56.        case 'C':case 'c':
  57.           decimal = 12;
  58.           break;
  59.        case 'D':case 'd':
  60.           decimal = 13;
  61.           break;
  62.        case 'E':case 'e':
  63.           decimal = 14;
  64.           break;
  65.        case 'F':case 'f':
  66.           decimal = 15;
  67.           break;
  68.        default:
  69.           printf("!Error!\n");
  70.    }
  71.    return decimal;
  72. }
  73.  
  74. char *convertirMayusculas(char *cadena)
  75. {
  76.    int i;
  77.    for(i = 0;cadena[i];i++)
  78.       cadena[i] = toupper(cadena[i]);
  79.    return cadena;
  80. }
  81.  
  82. int verificarRegistro(char *cadena)
  83. {
  84.    int i;
  85.    char *registro[] = {"X","Y","SP","PC"};
  86.    for(i = 0;i < 4;i++)
  87.    {
  88.        if((strcmp(cadena,registro[i])) == 0)
  89.           return 1;
  90.    }
  91.    return 0;
  92. }
  93.  
  94. int verificarRangoIndexadoIndirecto(int numero)
  95. {
  96.    if(numero >= CERO && numero <= MAX_IDX_INDIRECTO)
  97.       return 1;
  98.    else
  99.       return 0;
  100. }
  101.  

de antemano gracias


Título: Re: validar numeros
Publicado por: do-while en 5 Abril 2014, 02:54 am
¡Buenas!

Eso de los switch me parece un poco caótico. Yo lo que haría seria una función que me valide el código que le pasas y recoja los valores en los parámetros que le pases. Después, clasifica los parámetros como te convenga. Por ejemplo:
Código
  1. #include <ctype.h>
  2. #include <string.h>
  3.  
  4. /*
  5.     Si el formato no es correcto devuelve cero, sino uno.
  6.  
  7.     si la funcion devuelve 1 hay que comprobar si valor==-1 para saber si el primer
  8.     caracter desupues de [ es una D o no
  9. */
  10.  
  11. int validar_secuencia(char *s, int *valor, char codigo[3])
  12. {
  13.    char *codigos[] = {"x]","y]","sp]","pc]"};
  14.    int i;
  15.  
  16.    *valor = 0;
  17.  
  18.    if(!(*s))
  19.        return 0;
  20.  
  21.    if(s[0] != '[')
  22.        return 0;
  23.  
  24.    if(*(++s) == 'D')
  25.    {
  26.        *valor = -1;
  27.        s++;
  28.    }
  29.    else
  30.    {
  31.        while(*(++s) && isdigit(*s))
  32.        {
  33.            (*valor) *= 10;
  34.            (*valor) += (*s) - '0';
  35.        }
  36.    }
  37.  
  38.    if(!isdigit(*s) || *(s++) != ',')
  39.        return 0;
  40.  
  41.    for(i = 0 ; i < 4 ; i++)
  42.        if(!strcmp(s,codigos[i]))
  43.            break;
  44.  
  45.    if(i == 4)
  46.        return 0;
  47.  
  48.    strcpy(codigo,codigos[i]);
  49.    codigo[strlen(codigos[i]) - 1] = '\0';
  50.  
  51.    return *(s + strlen(codigos[i])) == '\0';
  52. }
  53.  
  54. int main(int argc, char *argv[])
  55. {
  56.    char *codigos[] = {"[123,x]","[1045,sp]","hola","[1,pc","[D,y]",""},codigo[3];
  57.    int i = 0,valor;
  58.  
  59.    while(codigos[i][0])
  60.    {
  61.        if(validar_secuencia(codigos[i],&valor,codigo))
  62.            printf("%s: Codigo correcto (valor=%d, codigo=%s)\n",codigos[i],valor,codigo);
  63.  
  64.        else
  65.            printf("%s: Codigo incorrecto\n",codigos[i]);
  66.  
  67.        i++;
  68.    }
  69. }
  70.  

De todas formas, si estás obligado a utilizar los switch veremos que se puede hacer. Ya diras.

¡Saludos!