Duda en en ejercicio de programacion

Iniciado por eaguel, 12 Noviembre 2012, 20:31 PM

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

eaguel

Hola buenas tardes, a ver si me podéis echar una mano con este programa

#include <stdio.h>
#define CTE 16
#define ERROR
#define NOERROR

int main ()

{

char car1 = '0';
char car2 = '0';
int valor1 = 0;
int valor2 = 0;
int valor = 0;
int cuno;
int cdos;

printf ("Introduzca un valor en Hexadecimal:");
scanf ("%c%c", &car1, &car2);

if ( ( ('0' <= car1) && (car1 <= '9') ) || ( ('A' <= car1) && (car1 <= 'F') ) || ( ('a' <= car1) && (car1 <= 'f') ) || ( ('0' <= car2) &&  (car2 <= '9') ) || ( ('A' <= car2) && (car2 <= 'F') ) || ( ('a' <= car2) && (car2 <= 'f') ) )
{
if ( ('0' <= car1) && (car1 <= '9') )
valor1 = car1 - '0';

else if  ( ('A' <= car1) && (car1 <= 'F') )
valor1 = car1 - 'A' + 10;
else
valor1 = car1 - 'a' + 10;

if ( ('0' <= car2) &&  (car2 <= '9') )
valor2 = car2 - '0';

else if  ( ('A' <= car2) && (car2 <= 'F') )
valor2 = car2 - 'A' + 10;
else
valor2 = car2 - 'a' + 10;


valor = CTE * valor1 + valor2;

printf("El valor decimal de 0x%c%c es %d\n", car1, car2, valor);
}
else if ( ( ('0' > car1) && (car1 > '9') ) || ( ('A' > car1) && (car1 > 'F') ) || ( ('a' > car1) && (car1 > 'f') ) )
{
printf ("Error en el primer valor introducido\n");
}
else if ( ( ('0' > car2) &&  (car2 > '9') ) || ( ('A' > car2) && (car2 > 'F') ) || ( ('a' > car2) && (car2 > 'f') ) )
{
printf ("Error en el segundo valor introducido\n");
}

return 0;

}


se supone que tiene que decir error en el primer valor introducido si esta mal el primero o error en el segundo si es el segundo, la idea del programa es convertir un número hexadecimal en decimal.
el problema es que cuando escrimo 1g me dice que es 32 y no me dice error en el segundo valor introducido

rir3760

El error es logico y se debe a la condición de la sentencia "if":
if ((('0' <= car1) && (car1 <= '9')) || (('A' <= car1) && (car1 <= 'F')) || ( ('a' <= car1) && (car1 <= 'f')) || (('0' <= car2) &&  (car2 <= '9') ) || ( ('A' <= car2) && (car2 <= 'F') ) || ( ('a' <= car2) && (car2 <= 'f')))

Antes de seguir un consejo: utiliza la función "isxdigit" (prototipo en <ctype.h>) para realizar la verificación. Al hacerlo la condición se reduce a:
if (isxdigit(car1) || isxdigit(car2)){
Espero ahora veas el error: realizas la conversión de los dos dígitos si alguno es valido.

Para solucionarlo hay que cambiar el uso del operador OR "||" por un AND "&&", con ello la condición sera verdadera solo si ambos operandos son verdaderos (en buen cristiano: solo si ambos caracteres son dígitos hexadecimales).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

eaguel

Eso ya lo arregle, gracias.
Pero ahora tengo otro problema mayor, copio el codigo

#include <stdio.h>
#define CTE 16
int main ()

{

char car1 = '0';
char car2 = '0';
int valor1 = 0;
int valor2 = 0;
int valor = 0;

do
{
  printf ("Introduzca un valor en Hexadecimal:");
  scanf ("%c%c", &car1, &car2);
  if ( ( ( ( car1 <= '9') && (car1 >= '0') ) || ( (car1 >= 'A') && ( car1 <= 'F') ) || ( (car1 >= 'a') && (car1 <= 'f') ) ) && ( ( (car2 >= '0') && (car2 <= '9') ) || ( (car2 >= 'A') || (car2 <= 'F') ) || ( (car2 >= 'a') || (car2 <= 'f') ) ) )

{
   if ( ('0' <= car1) && (car1 <= '9') )
valor1 = car1 - '0';

     else if  ( ('A' <= car1) && (car1 <= 'F') )
valor1 = car1 - 'A' + 10;
     
     else
valor1 = car1 - 'a' + 10;

     if ( ('0' <= car2) &&  (car2 <= '9') )
valor2 = car2 - '0';

     else if  ( ('A' <= car2) && (car2 <= 'F') )
valor2 = car2 - 'A' + 10;

     else
valor2 = car2 - 'a' + 10;
       


    valor = CTE * valor1 + valor2;

    printf("El valor decimal de 0x%c%c es %d\n", car1, car2, valor);

}
  if ( ( (car1 > '9' || car1 < '0') || car1 > 'F') || (car1 > 'f'))
   {
    printf ("Error en el primer valor introducido\n");
   }
  if ( ( (car2 > '9' || car2 < '0') &&  (car2 > 'f') ) )
   {
   printf ("Error en el segundo valor introducido\n");
   }
}
while ( (car1 != 'q') && (car2 != 'q');

return 0;

}


Ahora debería hacer un bucle para que me pidiera que introduzca un valor hasta que escriba "qq" pero cuando entra en el bucle se me distorsionan los valores, por ejemplo:
Un ejemplo de modo de funcionamiento correcto sería:

Introduzca el numero hexadecimal: 12
El valor decimal de 0x12 es 18
Introduzca el numero hexadecimal: 1B
El valor decimal de 0x1B es 27
Introduzca el numero hexadecimal: 1b
El valor decimal de 0x1b es 27
Introduzca el numero hexadecimal: 1G
Error en el segundo valor introducido
Introduzca el numero hexadecimal: g1
Error en el primer valor introducido
Introduzca el numero hexadecimal: Gg
Error en el primer valor introducido
Error en el segundo valor introducido
Introduzca el numero hexadecimal: A1
El valor decimal de 0xA1 es 161
Introduzca el numero hexadecimal: A2
El valor decimal de 0xA2 es 162
Introduzca el numero hexadecimal: AB
El valor decimal de 0xAB es 171
Introduzca el numero hexadecimal: qq



Cuando yo lo hago el primer valor si me da correcto, pero a partir de ay da un montón de errores y otro problema que tengo que no se corregir es que me considera que 'b' no es menor que  'F'

PD: gracias por la ayuda

Ferno

Sobre el primer problema. Es probable que se de debido a que no se limpia el buffer luego de cada scanf (y, así, se lee algún caracter de salto de línea en el medio). Prueba incluir esta línea luego de cada scanf:

while ((c = getchar()) != '\n');

Siendo "c" alguna variable que declares.

Sobre el problema que 'b' no es menor a 'F', en realidad es un problema con el algoritmo, debido que, justamente, el caracter 'b' (minúscula) efectivamente es MAYOR que 'F'. En la tabla ASCII las mayúsculas representan un código menor y así es como se comparan los caracteres. Por ende, deberías de ayudarte con las funciones tolower() o toupper() (cambiar de mayúscula a minúscula y viceverza) para terminar el code.

Saludos!

eaguel

#4
He solucionado el problema introduciendo dos variables nuevas cuno y cdos.
Ahora me piden que e de el resultado de un número hexadecimal de 4 carácteres, pero me da un error en el resultado, por ejemplo aaaa tendría que ser 43690 y a mi me da 734

#include <stdio.h>
#define CTE 16
#define NOERROR 1
#define ERROR 0
int hexValidos (char car1, char car2, char car3, char car4);

int main ()

{

char car1 = '0';
char car2 = '0';
char car3 = '0';
char car4 = '0';

hexValidos (car1, car2, car3, car4);

return 0;

}

int hexValidos (char car1, char car2, char car3, char car4)

{
int valor1  = 0;
int valor2  = 0;
int valor3  = 0;
int valor4  = 0;
int valor   = 0;
int cuno    = NOERROR;
int cdos    = NOERROR;
int ctres   = NOERROR;
int ccuatro = NOERROR;

do
{
  printf("Introduzca cuatro caracteres hexadecimales:");
  scanf("\n%c%c%c%c", &car1, &car2, &car3, &car4);

  if((('0' <= car1) && (car1 <= '9')) || (('A' <= car1) && (car1 <= 'F')) || (('a' <= car1) && (car1 <= 'f')))
   {
      if ( ('0' <= car1) && (car1 <= '9') )
        {
           valor1 = car1 - '0';
        }
       else if ( ('A' <= car1) && (car1 <= 'F'))
        {
           valor1 = car1 - 'A' + 10;
        }
       else if ( ('a' <= car1) && (car1 <= 'f'))
        {
           valor1 = car1 - 'A' + 10;
        }
    }

  else if ((car1 == 'q') && (car2 == 'q') && (car3 == 'q') && (car4 == 'q'))
    {
    }

  else
   {
     cuno = ERROR;
     printf("Invalido\n");
   }
 
  if((('0'<=car2) && (car2<='9')) || (('A'<=car2) && (car2<='F')) || (('a'<=car2) && (car2<='f')))
   {
       if ( ('0' <= car2) && (car2 <= '9') )
        {
           valor2 = car2 - '0';
        }
       else if ( ('A' <= car2) && (car2 <= 'F'))
        {
           valor2 = car2 - 'A' + 10;
        }
       else if ( ('a' <= car2) && (car2 <= 'f'))
        {
           valor2 = car2 - 'a' + 10;
        }
   }
  else if ((car1 == 'q') && (car2 == 'q') && (car3 == 'q') && (car4 == 'q'))
    {
    }
  else
   {
    cdos = ERROR;
    printf("Invalido\n");
   }

  if((('0' <= car3) && (car3 <= '9')) || (('A' <= car3) && (car3 <= 'F')) || (('a' <= car3) && (car3 <= 'f')))
   {
       if ( ('0' <= car3) && (car3 <= '9') )
        {
           valor3 = car3 - '0';
        }
       else if ( ('A' <= car2) && (car2 <= 'F'))
        {
           valor3 = car3 - 'A' + 10;
        }
       else if ( ('a' <= car3) && (car3 <= 'f'))
        {
           valor3 = car3 - 'a' + 10;
        }
   }
  else if ((car1 == 'q') && (car2 == 'q') && (car3 == 'q') && (car4 == 'q'))
    {
    }
  else
   {
    ctres = ERROR;
    printf("Invalido\n");

   }
  if((('0' <= car4) && (car4 <= '9')) || (('A' <= car4) && (car4 <= 'F')) || (('a' <= car4) && (car4 <= 'f')))
   {
       if ( ('0' <= car4) && (car4 <= '9') )
        {
           valor4 = car3 - '0';
        }
       else if ( ('A' <= car4) && (car4 <= 'F'))
        {
           valor4 = car4 - 'A' + 10;
        }
       else if ( ('a' <= car4) && (car4 <= 'f'))
        {
           valor4 = car4 - 'a' + 10;
        }
   }
  else if ((car1 == 'q') && (car2 == 'q') && (car3 == 'q') && (car4 == 'q'))
    {
    }
  else
   {
    ccuatro = ERROR;
    printf("Invalido\n");
   }
   
 
  if ((cuno != ERROR) && (cdos != ERROR) && (ctres != ERROR) && (ccuatro != ERROR))
   {
      valor = CTE * valor1 + valor2 + valor3 + valor4;
      printf("El valor decimal de 0x%c%c%c%c es %d\n", car1, car2, car3, car4, valor);
   }
}
while ( (car1 != 'q') && (car2 != 'q') && (car3 != 'q') && (car4 != 'q') );

return valor;
}

rir3760

No quiero sonar grosero pero, honestamente, el programa es demasiado largo para la operación a realizar. Como ya te comente lo puedes reducir bastante utilizando la función "isxdigit".

El primer error se encuentra al obtener el primer dígito:

} else if ( ('a' <= car1) && (car1 <= 'f') ) {
   valor1 = car1 - 'A' /* <== */ + 10;
}


El segundo al calcular el valor del numero:
#define CTE 16

/* ... */

valor = CTE * valor1 + valor2 + valor3 + valor4;


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

eaguel

Muchas gracias ya conseguí hacerlo, gracias por la ayuda