[C] Problema al leer un char dentro de un while

Iniciado por cesariox23, 29 Diciembre 2014, 03:06 AM

0 Miembros y 2 Visitantes están viendo este tema.

cesariox23

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.


/* Convertidor de colores hexadecimales a colores RGB */
#include <stdio.h>

/* Función que devuelve el valor decimal de una cifra hexadecimal */
int hex_to_dec(char letra);

int main(void)
{
    char color[7];
    char respuesta = 115;
    int rgb[3];
    int contador, factor, position;

    /* 110 = Valor ASCII de la letra n
       115 = Valor ASCII de la letra s */
    while(respuesta != 110)    // Aca puse anteriormente while(respuesta != 'n') pero no funciono
    {
        /* Inicializando valores */
        for(contador = 0; contador <= 2; contador++)
            rgb[contador]= 0;

        position = 0;

        /* Ingresando el color en hexadecimal */
        printf("Color hexadecimal: ");
        scanf("%s", color);

        /* Iniciando procesamiento de datos para hallar el color RGB */
        for(contador = 0; color[contador] != '\0'; contador++)
        {
            factor = (contador % 2 == 0) ? 16 : 1;

            if(color[contador] >= 49 && color[contador] <= 57)
                rgb[position] += (color[contador] - 48) * factor;
            else if(color[contador] >= 97 && color[contador] <= 102)
                rgb[position] += hex_to_dec(color[contador]) * factor;
            else if(color[contador] >= 65 && color[contador] <= 70)
                rgb[position] += hex_to_dec(color[contador]) * factor;

            if(factor == 1)
                position++;
        }

        /* Mostrando los valores decimales del número hexadecimal */
        printf("RGB: ");
        for(contador = 0; contador <= 2; contador++)
        {
            if(contador == 2)
                printf("%d", rgb[contador]);
            else
                printf("%d - ", rgb[contador]);
        }
        printf("\n");

        /* Preguntando respuesta para continuar */
        printf("Continuar? s/n: ");
        scanf("%d", &respuesta);    // Aca puse anteriormente scanf("%c", &respuesta) pero el programa no ejecutaba el scanf
        printf("\n");
    }

    return 0;
}

/* Definiendo la función que devuelve el valor decimal de una cifra hexadecimal */
int hex_to_dec(char letra)
{
    int contador;
    static int base = 10;
    static char minusculas[6] = {'a', 'b', 'c', 'd', 'e', 'f'};
    static char mayusculas[6] = {'A', 'B', 'C', 'D', 'E', 'F'};

    /* Recorriendo el arreglo para encontrar coincidencias */
    for(contador = 0; contador <= 5; contador++)
    {
        if(letra == minusculas[contador] || letra == mayusculas[contador])
            break;
    }

    return base + contador;
}


crack81

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
Si C/C++ es el padre de los lenguajes entonces ASM es dios.

rir3760

Cita de: cesariox23 en 29 Diciembre 2014, 03:06 AMEl 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í:
unsigned r;
unsigned g;
unsigned b;

while (scanf("%2x%2x%2x", &r, &g, &b) == 3)
   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.

----

Cita de: crack81 en 29 Diciembre 2014, 21:18 PMpara 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
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