C - Problema con scanf y string

Iniciado por Xargam, 15 Abril 2018, 20:21 PM

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

Xargam

Hola gente, estoy haciendo una funcion que pide string (caracteres limitados). Tengo una funcion en la que al scanf le asigne %[^\n] para que tome los espacios del string. Tambien quiero tener otra funcion que pida string hasta que encuentre un espacio, por lo que cambie la mascara por %s. Encontre un problema grave en esta segunda funcion:


void getRangedSimStr(char* vec,char message[],char eMessage[],int minChars, int maxChars)
{
    char palabra[1000];
    printf("%s", message);
    setbuf(stdin,NULL);
    scanf("%s",palabra);
    setbuf(stdin,NULL);
    while(strlen(palabra) > maxChars || strlen(palabra) < minChars)
    {
        printf("%s",eMessage);
        scanf("%s",palabra);
        setbuf(stdin,NULL);
    }
    strcpy(vec,  palabra);
}


Al momento de ser ejecutada en un bucle for de 3 iteraciones y guardado el string en una matriz con este codigo:


    char matriz[CANT][CHARS];
    char primeraLetra;
    for(int i = 0; i< CANT; i++)
    {
        printf("Ingrese nombre %d: ",i+1);
        getRangedSimStr(matriz[i],"","Nombre invalido, reingrese: ",1,49);
        strlwr(matriz[i]);
        primeraLetra = matriz[i][0];
        primeraLetra = toupper(primeraLetra);
        matriz[i][0] = primeraLetra;

    }
    for(int i = 0; i < CANT; i++)
    {
        printf("%s\n",matriz[i]);
    }


Si yo escribo "SPORE ES BUENO" el bucle for no me pide la segunda y la tercera vez que ingrese string. Muestra la matriz con SPORE en indice 0, ES en el indice 1 y BUENO en el indice 2.
Miren:


MAFUS

Cambia lo de setbuf(stdin, NULL); por while(getchar()!='\n'); tal que así:
void getRangedSimStr(char* vec,char message[],char eMessage[],int minChars, int maxChars)
{
    char palabra[1000];
    printf("%s", message);
    scanf("%s",palabra);
    while(getchar()!='\n');
    while(strlen(palabra) > maxChars || strlen(palabra) < minChars)
    {
        printf("%s",eMessage);
        scanf("%s",palabra);
        while(getchar()!='\n');
    }
    strcpy(vec,  palabra);
}

stdin, stdout y stderr todo y que son tratados como archivos no lo son, y por esa razón tienen sus manías.

Xargam

#2
Excelente ahora funcione perfecto!!! gracias pero no entendi que es lo que hace ese codigo... Si ingreso "spore es bueno", me queda " es bueno\n" en el buffer. Como un bucle while vacio limpia el buffer??'

MAFUS

Cuando capturas una frase que contenga espacios el %s de scanf adquiere datos hasta llegar al primer espacio en blanco.
Los datos restantes quedarán en el buffer y al volver a usar scanf adquirirá desde la última posición en que quedó.
Nosotros, al concluir un escrito con la tecla RETURN, añadimos al final de todo un carácter de nueva línea '\n' y eso lo podemos usar como marcador de final de buffer stdin.
while(getchar()!='\n'); hacemos que getchar vaya adquiriendo (y quitando) caracteres de uno en uno del buffer hasta que encuentre el de nueva línea, momento en que el bucle while se detendrá y el bucle quedará vacío.

Xargam