/*
 * Modulo: leituras.c
 *
 * Descricao:
 *    Este modulo define algumas funcoes que simplificam a leitura de
 * valores do teclado.
 *
 * Autores:
 *    Manuel Menezes de Sequeira, ISCTE.
 *
 * Notas:
 *
 * Historia:
 *    Autor:              Data:                  Notas:
 *    MMS                 1996/4/19              primeira versao
 *
 * Copyright (c) ISCTE, 1996.
 */

/* A inclusao de stdlib.h e' necessaria para que a macro EXIT_FAILURE seja
   convenientemente definida. */
#include <stdlib.h>
#include <stdio.h>

#include "leituras.h"


/*
 * Funcao: LEmataLinha()
 *
 * Accao: 
 *    Elimina todos os caracteres ate' ao proximo fim-de-linha ou ate' ao
 * fim do ficheiro.
 *
 * Parametros:
 *    Nao tem.
 *
 * Devolve:
 *    Nada.
 */
void LEmataLinha(void)

{
    int c;
    
    while((c = getchar()) != '\n' && c != EOF)
        /* Nada. */;
}


/*
 * Funcao: LEvalor()
 *
 * Accao:
 *    Le um valor inteiro do teclado, com uma determinada gama, e devolve-o. 
 *
 * Parametros:
 *    mensagem (entrada) - mensagem de pedido de entrada a imprimir.
 *    min, max (entrada) - especificam gama admissivel para o valor n lido: se
 *        min < max, min <= n <= max, se min == max, n >= min, se min > max,
 *        nao ha' restricoes ao valor de n.
 *
 * Devolve:
 *    O valor lido.
 *
 * Erros:
 *    Caso seja atingido o fim da entrada (stdin) o programa e' abortado.
 */
int LEvalor(const char *mensagem, int min, int max)

{
    int n, res;
    int valido;

    do
    {
	if(min == max)
	    printf(mensagem, min);
	else if(min > max)
	    printf(mensagem);
	else
	    printf(mensagem, min, max);
        if((res = scanf("%d", &n)) == EOF)
        {
            fprintf(stderr, "Erro: lendo valor!\n");
            exit(EXIT_FAILURE);
        }
	if(min == max)
	    valido = (n >= min);
	else if(min > max)
	    valido = 1;
	else
	    valido = (n >= min && n <= max);
	LEmataLinha();
    }
    while(res != 1 || !valido);

    return n;
}       
            

/*
 * Funcao: LEdouble()
 *
 * Accao:
 *    Le um valor double do teclado.
 *
 * Parametros:
 *    mensagem (entrada) - mensagem de pedido de entrada a imprimir.
 *
 * Devolve:
 *    O valor lido.
 *
 * Erros:
 *    Caso seja atingido o fim da entrada (stdin) o programa e' abortado.
 */
double LEdouble(const char *mensagem)

{
    int res;
    double v;

    do
    {
	printf(mensagem);
        if((res = scanf("%lg", &v)) == EOF)
        {
            fprintf(stderr, "Erro: lendo double!\n");
            exit(EXIT_FAILURE);
        }
	LEmataLinha();
    }
    while(res != 1);

    return v;
}       
            

/*
 * Funcao: LEnome()
 *
 * Accao:
 *    Le uma cadeia de caracteres, consistindo apenas de letras, espacos ou
 * pontos, do teclado.
 *
 * Parametros:
 *    mensagem (entrada) - mensagem de pedido de entrada e imprimir.
 *    nome (saida) - cadeia para onde ler.
 *    dimensao (entrada) - numero maximo de caracteres a ler.
 *
 * Devolve:
 *    Nada.
 *
 * Erros:
 *    Caso seja atingido o fim da entrada (stdin) o programa e' abortado.
 */
void LEnome(const char *mensagem, char *nome, int dimensao)

{
    char formato[100];
    int res;
    
    sprintf(formato, "%%%d[a-z.A-Z ]", dimensao);
    do
    {
        printf(mensagem);
        if((res = scanf(formato, nome)) == EOF)
        {
            fprintf(stderr, "Erro: lendo nome!\n");
            exit(EXIT_FAILURE);
        }
	LEmataLinha();		/* para eliminar resto da linha. */
    }
    while(res != 1 || nome[0] == '\0');
}


/*
 * Funcao: LEcadeia()
 *
 * Accao:
 *    Le uma cadeia de caracteres nao-brancos.
 *
 * Parametros:
 *    mensagem (entrada) - mensagem de pedido de entrada e imprimir.
 *    nome (saida) - cadeia para onde ler.
 *    dimensao (entrada) - numero maximo de caracteres a ler.
 *
 * Devolve:
 *    Nada.
 *
 * Erros:
 *    Caso seja atingido o fim da entrada (stdin) o programa e' abortado.
 */
void LEcadeia(const char *mensagem, char *nome, int dimensao)

{
    char formato[100];
    int res;
    
    sprintf(formato, "%%%ds", dimensao);
    do
    {
        printf(mensagem);
        if((res = scanf(formato, nome)) == EOF)
        {
            fprintf(stderr, "Erro: lendo cadeia!\n");
            exit(EXIT_FAILURE);
        }
	LEmataLinha();		/* para eliminar resto da linha. */
    }
    while(res != 1 || nome[0] == '\0');
}