Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: cesariox23 en 29 Diciembre 2014, 03:06 am



Título: [C] Problema al leer un char dentro de un while
Publicado por: cesariox23 en 29 Diciembre 2014, 03:06 am
Estimados señores: El día de hoy empecé a codificar un programa que me permitiría obtener los componentes RGB de una cadena hexadecimal de color, si yo ingresara 6c6c6c me devolvería (108, 108, 108), el programa estaría hecho para realizar varias conversiones consecutivas asi que consideré correcto incorporar un while y preguntar al usuario si quiere continuar luego de cada conversión, el usuario respondería solo con 2 opciones: s ó n, el detalle es que no he conseguido que el programa me reconozca el char ingresado por el usuario, logré arreglarlo momentáneamente para que me reconozca el valor numérico de los caracteres pero eso se aleja de la idea original, no logro encontrar la falla en mi código y en verdad agradecería cualquier ayuda o crítica constructiva que puedan brindarme.

El entorno de programación que estoy utilizando es:
Codeblocks 10050 (http://forums.codeblocks.org/index.php/board,20.0.html)
MinGW-w64 4.9.2 POSIX - DWARF (http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/)

Este es el código que he escrito hasta ahora.

Código
  1. /* Convertidor de colores hexadecimales a colores RGB */
  2. #include <stdio.h>
  3.  
  4. /* Función que devuelve el valor decimal de una cifra hexadecimal */
  5. int hex_to_dec(char letra);
  6.  
  7. int main(void)
  8. {
  9.    char color[7];
  10.    char respuesta = 115;
  11.    int rgb[3];
  12.    int contador, factor, position;
  13.  
  14.    /* 110 = Valor ASCII de la letra n
  15.        115 = Valor ASCII de la letra s */
  16.    while(respuesta != 110)    // Aca puse anteriormente while(respuesta != 'n') pero no funciono
  17.    {
  18.        /* Inicializando valores */
  19.        for(contador = 0; contador <= 2; contador++)
  20.            rgb[contador]= 0;
  21.  
  22.        position = 0;
  23.  
  24.        /* Ingresando el color en hexadecimal */
  25.        printf("Color hexadecimal: ");
  26.        scanf("%s", color);
  27.  
  28.        /* Iniciando procesamiento de datos para hallar el color RGB */
  29.        for(contador = 0; color[contador] != '\0'; contador++)
  30.        {
  31.            factor = (contador % 2 == 0) ? 16 : 1;
  32.  
  33.            if(color[contador] >= 49 && color[contador] <= 57)
  34.                rgb[position] += (color[contador] - 48) * factor;
  35.            else if(color[contador] >= 97 && color[contador] <= 102)
  36.                rgb[position] += hex_to_dec(color[contador]) * factor;
  37.            else if(color[contador] >= 65 && color[contador] <= 70)
  38.                rgb[position] += hex_to_dec(color[contador]) * factor;
  39.  
  40.            if(factor == 1)
  41.                position++;
  42.        }
  43.  
  44.        /* Mostrando los valores decimales del número hexadecimal */
  45.        printf("RGB: ");
  46.        for(contador = 0; contador <= 2; contador++)
  47.        {
  48.            if(contador == 2)
  49.                printf("%d", rgb[contador]);
  50.            else
  51.                printf("%d - ", rgb[contador]);
  52.        }
  53.        printf("\n");
  54.  
  55.        /* Preguntando respuesta para continuar */
  56.        printf("Continuar? s/n: ");
  57.        scanf("%d", &respuesta);    // Aca puse anteriormente scanf("%c", &respuesta) pero el programa no ejecutaba el scanf
  58.        printf("\n");
  59.    }
  60.  
  61.    return 0;
  62. }
  63.  
  64. /* Definiendo la función que devuelve el valor decimal de una cifra hexadecimal */
  65. int hex_to_dec(char letra)
  66. {
  67.    int contador;
  68.    static int base = 10;
  69.    static char minusculas[6] = {'a', 'b', 'c', 'd', 'e', 'f'};
  70.    static char mayusculas[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
  71.  
  72.    /* Recorriendo el arreglo para encontrar coincidencias */
  73.    for(contador = 0; contador <= 5; contador++)
  74.    {
  75.        if(letra == minusculas[contador] || letra == mayusculas[contador])
  76.            break;
  77.    }
  78.  
  79.    return base + contador;
  80. }
  81.  


Título: Re: [C] Problema al leer un char dentro de un while
Publicado por: T. Collins en 29 Diciembre 2014, 04:23 am
Mira el punto 1 y 2 de este enlace:
http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html)

y esto también:
http://foro.elhacker.net/programacion_cc/error_super_basico_en_c_quien_me_ayuda_soy_nuevo-t262118.14.html (http://foro.elhacker.net/programacion_cc/error_super_basico_en_c_quien_me_ayuda_soy_nuevo-t262118.14.html)


Título: Re: [C] Problema al leer un char dentro de un while
Publicado por: crack81 en 29 Diciembre 2014, 21:18 pm
Tu problema es la funcion   scanf("%c", &respuesta); en ocasiones no funciona bien, y no absorbe esa pulsación de Intro que ha quedado en el buffer del teclado después de la lectura del caracter.

Ese es el riesgo cuando usas "scanf" para leer caracteres, especialmente si lo mezclas con otras cosas

para corregir el error duplica la funcion   scanf("%c", &respuesta); y veras que ya funciona o usa arreglo de caracteres y solo coge la primera posicion


Título: Re: [C] Problema al leer un char dentro de un while
Publicado por: rir3760 en 30 Diciembre 2014, 04:13 am
El día de hoy empecé a codificar un programa que me permitiría obtener los componentes RGB de una cadena hexadecimal de color, si yo ingresara 6c6c6c me devolvería (108, 108, 108)
Si es para practicar, parte de tu proceso de aprendizaje del lenguaje C no hay problema. Pero hay que indicar que dicha operación se puede realizar de forma mas corta mediante scanf, mas o menos así:
Código
  1. unsigned r;
  2. unsigned g;
  3. unsigned b;
  4.  
  5. while (scanf("%2x%2x%2x", &r, &g, &b) == 3)
  6.   printf("%x\n%x\n%x\n\n", r, g, b);
En la llamada a scanf el especificador "%2x" indica que se consumirá un máximo de dos caracteres validos para la conversión (dígitos en base 16) y el valor de retorno se verifica para asegurarnos de que se leyeron los tres números correctamente.

----

para corregir el error duplica la funcion   scanf("%c", &respuesta);
En este caso en particular (carácter '\n' de la linea anterior en el bufer de la entrada estándar) no es necesario duplicar la llamada a función, en su lugar basta con utilizar la cadena de formato " %c" donde el espacio al inicio de ella le indica a scanf que primero descarte todos los caracteres de espacio blanco (espacio, avance de linea, etc.) que encuentre, solo entonces se leerá el carácter y almacenara en la dirección indicada.

Un saludo