validar numeros

Iniciado por m@o_614, 5 Abril 2014, 02:17 AM

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

m@o_614

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

case INDEXADO_INDIRECTO:
           i = 1;
           tam = strlen(operando);
           car = operando[i++];
           if(car == '\0')
              printf("Despues del primer [ debe haber dos registros separados por , y un corchete de cierre\n");
           else
           {
               if(operando[tam-1] != ']')
                  printf("Error: No se encontro corchete de cierre\n");
               else
               {
                   switch(car)
                   {
                       case ']':
                          printf("No pueden estar los corchetes vacios\n");
                          break;
                       case ',':
                          printf("No puede haber una instruccion vacia antes de la coma\n");
                          registro = obtenerRegistro(operando);
                          if((strcmp(registro,"\0")) == 0)
                             printf("No puede haber una instruccion vacia despues de la coma\n");
                             break;
                       case '0':
                       case '1':
                       case '2':
                       case '3':
                       case '4':
                       case '5':
                       case '6':
                       case '7':
                       case '8':
                       case '9':
                          if((ptr = strchr(operando,',')) == 0)
                             printf("Despues del primer corchete debe haber dos registros separados por una ,\n");
                          else
                          {
                              base = 10;
                              x = 1;
                              k = 0;
                              esIndexadoIndirecto16bits = 1;
                              instruccion = obtenerInstruccion(operando,x);
                              numero = obtenerNumero(instruccion,k,base);
                              registro = obtenerRegistro(operando);
                              registro = convertirMayusculas(registro);
                              if((strcmp(registro,"\0")) == 0)
                                 printf("No puede haber una instruccion vacia despues de la coma\n");
                              else
                              {
                                  if(!verificarRegistro(registro))
                                  {
                                      esIndexadoIndirecto16bits = 0;
                                      printf("Los registros validos de un direccionamiento Indexado indirecto de 16 bits son X,Y,SP,PC\n");
                                  }
                                  if(!verificarRangoIndexadoIndirecto(numero))
                                  {
                                      esIndexadoIndirecto16bits = 0;
                                      printf("El rango valido de un direccionamiento Indexado Indirecto de 16 bits es de 0 a 65535\n");
                                  }
                                  if(esIndexadoIndirecto16bits)
                                  {
                                      if((indice = buscarDireccionamiento(encontrado,direccionamiento[7]))!= -1)
                                         printf("Indexado Indirecto de 16 bits([IDX2]), de %s bytes\n",encontrado->total_bytes[indice]);
                                      else
                                         printf("el codop %s no acepta el direccionamiento indexado indirecto de 16 bits\n",encontrado->instruccion);
                                  }
                              }
                          }
                         break;
                      case '-':
                         if((ptr = strchr(operando,',')) == 0)
                            printf("Despues del primer corchete debe haber dos registros separados por una ,\n");
                         else
                         {
                             base = 10;
                             x = 0;
                             k = 1;
                             esIndexadoIndirecto16bits = 1;
                             instruccion = obtenerInstruccion(operando,x);
                             numero = obtenerNumero(instruccion,k,base);
                             registro = obtenerRegistro(operando);
                             registro = convertirMayusculas(registro);
                             if((strcmp(registro,"\0")) == 0)
                                printf("No puede haber una instruccion vacia despues de la coma\n");
                             else
                             {
                                 if(!verificarRegistro(registro))
                                 {
                                     esIndexadoIndirecto16bits = 0;
                                     printf("Los registros validos de un direccionamiento Indexado indirecto de 16 bits son X,Y,SP,PC\n");
                                 }
                                 if(!verificarRangoIndexadoIndirecto(numero))
                                 {
                                     esIndexadoIndirecto16bits = 0;
                                     printf("El rango valido de un direccionamiento Indexado Indirecto de 16 bits es de 0 a 65535\n");
                                 }
                                 if(esIndexadoIndirecto16bits)
                                 {
                                     if((indice = buscarDireccionamiento(encontrado,direccionamiento[7]))!= -1)
                                        printf("Indexado Indirecto de 16 bits([IDX2]), de %s bytes\n",encontrado->total_bytes[indice]);
                                     else
                                        printf("el codop %s no acepta el direccionamiento indexado indirecto de 16 bits\n",encontrado->instruccion);
                                 }
                             }
                         }
                         break;
                      default:
                         x = 1;
                         esIndexadoIndirecto_Acumulador = 1;
                         instruccion = obtenerInstruccion(operando,x);
                         registro = obtenerRegistro(operando);
                         registro = convertirMayusculas(registro);
                         if(!indirectoAcumulador_D(instruccion))
                         {
                             printf("Error: El Acumulador valido de un Indexdo Indirecto de acumulador es D\n");
                             esIndexadoIndirecto_Acumulador = 0;
                         }
                         if(!verificarRegistro(registro))
                         {
                             printf("Los registros validos de un Indexado Indirecto de Acumulador son X,Y,SP,PC\n");
                             esIndexadoIndirecto_Acumulador = 0;
                         }
                         if(esIndexadoIndirecto_Acumulador)
                         {
                             if((indice = buscarDireccionamiento(encontrado,direccionamiento[6]))!= -1)
                                printf("Indexado Indirecto de Acumulador D,([D,IDX]), de %s bytes\n",encontrado->total_bytes[indice]);
                             else
                                printf("el codop %s no acepta el direccionamiento indexado indirecto de acumulador D\n",encontrado->instruccion);
                         }
                     }
               }
           }
           break;


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.

char *obtenerRegistro(char *operando)
{
   int j,i = 0;
   char *cadena = NULL,c[2];
   cadena = calloc(2,sizeof(char));
   while(operando[i] != ',')
      i++;
   for(j = i+1;operando[j] != ']';j++)
   {
       sprintf(c,"%c",operando[j]);
       strcat(cadena,c);
   }
   return cadena;
}
char *obtenerInstruccion(char *operando,int x)
{
   int i;
   char *cadena = NULL,c[2],signo[] = {'\0',','};
   cadena = calloc(7,sizeof(char));
   for(i = x;operando[i] != ',';i++)
   {
       sprintf(c,"%c",operando[i]);
       strcat(cadena,c);
   }
   return cadena;
}

int obtenerNumero(char *operando,int x,int base)
{
   int i,potencia,num_decimal = 0,lon,entero = 0;
   lon = strlen(operando);
   for(i = lon-1,potencia = 1;i >= x;i--,potencia*=base)
   {
       if(esLetraBase16(operando[i]))
          entero = hexadecimal(operando[i]);
       else
          entero = operando[i]-'0';
       num_decimal+= potencia*entero;
   }
   if(operando[CERO] == '-')
      num_decimal*= -1;
   return num_decimal;
}

int hexadecimal(char caracter)
{
   int decimal;
   switch(caracter)
   {
       case 'A':case 'a':
          decimal = 10;
          break;
       case 'B':case 'b':
          decimal = 11;
          break;
       case 'C':case 'c':
          decimal = 12;
          break;
       case 'D':case 'd':
          decimal = 13;
          break;
       case 'E':case 'e':
          decimal = 14;
          break;
       case 'F':case 'f':
          decimal = 15;
          break;
       default:
          printf("!Error!\n");
   }
   return decimal;
}

char *convertirMayusculas(char *cadena)
{
   int i;
   for(i = 0;cadena[i];i++)
      cadena[i] = toupper(cadena[i]);
   return cadena;
}

int verificarRegistro(char *cadena)
{
   int i;
   char *registro[] = {"X","Y","SP","PC"};
   for(i = 0;i < 4;i++)
   {
       if((strcmp(cadena,registro[i])) == 0)
          return 1;
   }
   return 0;
}

int verificarRangoIndexadoIndirecto(int numero)
{
   if(numero >= CERO && numero <= MAX_IDX_INDIRECTO)
      return 1;
   else
      return 0;
}


de antemano gracias

do-while

#1
¡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:

#include <ctype.h>
#include <string.h>

/*
   Si el formato no es correcto devuelve cero, sino uno.

   si la funcion devuelve 1 hay que comprobar si valor==-1 para saber si el primer
   caracter desupues de [ es una D o no
*/

int validar_secuencia(char *s, int *valor, char codigo[3])
{
   char *codigos[] = {"x]","y]","sp]","pc]"};
   int i;

   *valor = 0;

   if(!(*s))
       return 0;

   if(s[0] != '[')
       return 0;

   if(*(++s) == 'D')
   {
       *valor = -1;
       s++;
   }
   else
   {
       while(*(++s) && isdigit(*s))
       {
           (*valor) *= 10;
           (*valor) += (*s) - '0';
       }
   }

   if(!isdigit(*s) || *(s++) != ',')
       return 0;

   for(i = 0 ; i < 4 ; i++)
       if(!strcmp(s,codigos[i]))
           break;

   if(i == 4)
       return 0;

   strcpy(codigo,codigos[i]);
   codigo[strlen(codigos[i]) - 1] = '\0';

   return *(s + strlen(codigos[i])) == '\0';
}

int main(int argc, char *argv[])
{
   char *codigos[] = {"[123,x]","[1045,sp]","hola","[1,pc","[D,y]",""},codigo[3];
   int i = 0,valor;

   while(codigos[i][0])
   {
       if(validar_secuencia(codigos[i],&valor,codigo))
           printf("%s: Codigo correcto (valor=%d, codigo=%s)\n",codigos[i],valor,codigo);

       else
           printf("%s: Codigo incorrecto\n",codigos[i]);

       i++;
   }
}


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

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!