Hacer dos comprobaciones en un WHILE con funciones

Iniciado por RGT, 5 Noviembre 2015, 04:46 AM

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

RGT

Hola, gracias por guiarme todo este tiempo.
Tengo un nuevo problema con mi programa.

Mi código:

#include <iostream>
#include <fstream>  // Librería para el manejo de archivos
#include <string>   // Librería para el manejo de strings
#include <stdlib.h> // Librería para el uso de system("cls");
#include <ctype.h>  // Librería para clasificar y transformar caracteres individuales

using namespace std;

bool ValidarNumeroIngresado(string NumeroLetras);
bool ValidarPalabra(int NumeroLetras, fstream &FicheroPalabras);

int main()
{
    //Declaración de variables
    fstream FicheroPalabras;
    string NumeroLetras, Palabra;

/*  Creamos el fichero con las palabras a adivinar
------------------------------------------------------------------------*/
    cout << "Creando fichero con palabras..." << endl;
    FicheroPalabras.open("palabras.txt", ios::out);
    FicheroPalabras << "baloncesto\n";
    FicheroPalabras << "beisbol\n";
    FicheroPalabras << "futbol\n";
    FicheroPalabras << "golf\n";
    FicheroPalabras << "rugby\n";
    FicheroPalabras << "tenis\n";
    FicheroPalabras << "boxeo\n";
    FicheroPalabras << "sumo\n";
    FicheroPalabras << "judo\n";
    FicheroPalabras << "nascar\n";
    FicheroPalabras << "atletismo\n";
    FicheroPalabras << "caminata\n";
    FicheroPalabras << "ciclismo\n";
    FicheroPalabras << "esgrima\n";
    FicheroPalabras << "natacion\n";
    FicheroPalabras << "polo\n";
    FicheroPalabras << "clavados\n";
    FicheroPalabras << "remo\n";
    FicheroPalabras << "vela\n";
    FicheroPalabras << "ajedrez";
    FicheroPalabras.close();
    cout << "Fichero creado exitosamente..." << endl;

/*  Header del programa
------------------------------------------------------------------------*/
    cout << "\nJuego de El Ahorcado\n--------------------" << endl;
    cout << "Tema: Deportes\n" << endl;

/*  Content del programa
------------------------------------------------------------------------*/
    do
    {
        cout << "N\243mero de letras de la palabra: ";
        getline(cin, NumeroLetras);
    } while(ValidarNumeroIngresado(NumeroLetras) && ValidarPalabra(atoi(NumeroLetras.c_str()), FicheroPalabras));

    return 0;
}

/*  Validar el número ingresado
------------------------------------------------------------------------*/
bool ValidarNumeroIngresado(string NumeroLetras)
{
    /*
        La función "isdigit" revisa que todos los caracteres de la cadena sean números.
        Esta función perternece a la Librería <ctype.h>.
    */

    if (isdigit(NumeroLetras[0]))
    {
        cout << "\n\tEnhorabuena!, n\243mero v\240lido...\n" << endl;
        return false;
    }

    else
    {
        cout << "\n\tError!, n\243mero inv\240lido...\n" << endl;
        return true;
    }
}

/*  Validar que exista una palabra con el número de letras ingresado
------------------------------------------------------------------------*/
bool ValidarPalabra(int NumeroLetras, fstream &FicheroPalabras)
{
    string Palabra;
    bool PalabraEncontrada = true;

    FicheroPalabras.open("palabras.txt", ios::in);

    while (PalabraEncontrada)
    {
        if (FicheroPalabras.eof())
        {
            PalabraEncontrada = false;
            cout << "Error!, no hay palabras de " << NumeroLetras << " letras en el juego..." << endl;
            return true;
        }

        else
        {
            getline(FicheroPalabras, Palabra);

            if (Palabra.size() == NumeroLetras)
            {
                PalabraEncontrada = false;
                cout << "Palabra de " << NumeroLetras << " letras encontrada..." << endl;
                return false;
            }
        }
    }

    FicheroPalabras.close();
}


Debo replicar el juego de EL AHORCADO.

Pasos que hago:

  • Pido el número de letras que debe tener la palabra a adivinar.
  • Con la función "ValidarNumeroIngresado" valido que el dato ingresado sea un número y no cualquier otra cosa.
  • Con la función "ValidarPalabra" valido que exista una palabra con esa cantidad de letras.

Entonces, quiero que el programa siga pidiendo el número de letras siempre y cuando:

  • El dato ingresado no sea un número.
  • Exista una palabra con la cantidad de letras.

Cómo hago esas dos validaciones dentro del WHILE?, no se me ocurre otra cosa y he dado mucha cabeza en este asunto.
Pensé que me iba a funcionar la forma que tengo, pero no funciona.

Alguna ayuda por favor de alguien con experiencia en estos casos?.

Ahora mismo el programa funciona, pero no me muestra los mensajes de que si encontró o no una palabra con esa cantidad de letras (segunda validación en el WHILE), estoy pensando que el programa esta obviando esa parte.

Ayuda por favor :(

class_OpenGL

#1
En primer lugar, cuando llamas a la función ValidarNumeroIngresado(NumeroLetras), lo que haces es comprobar que el primer carácter sea un dígito. No compruebas que toda la cadena sea un número. Lo segundo, que para convertir la cadena en un entero, es mejor usar la función strtol, pues si hay algún error, será más previsible. En tercer lugar, ¿por qué no pides directamente un entero?

Código (cpp) [Seleccionar]
do {
   std::cout << "N\243mero de letras de la palabra: ";

   if(std::cin.fail()) { // Comprobamos si hay errores de entrada
       std::cin.clear();
       std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Limpiamos el buffer manejado por la clase std::cin
   }

   std::cin >> nNumLetters;
} while(std::cin.fail());


La variable nNumLetters es de tipo int

Te aconsejo mirar el tema que publiqué hace poco sobre el funcionamiento del operador std::cin>> para una mejor comprensión del código.

http://foro.elhacker.net/programacion_cc/aporte_diagrama_de_flujo_del_operador_stdcin_stdistream-t443774.0.html

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

RGT

Cita de: class_OpenGL en  5 Noviembre 2015, 08:33 AM
En primer lugar, cuando llamas a la función ValidarNumeroIngresado(NumeroLetras), lo que haces es comprobar que el primer carácter sea un dígito. No compruebas que toda la cadena sea un número. Lo segundo, que para convertir la cadena en un entero, es mejor usar la función strtol, pues si hay algún error, será más previsible. En tercer lugar, ¿por qué no pides directamente un entero?

Código (cpp) [Seleccionar]
do {
   std::cout << "N\243mero de letras de la palabra: ";

   if(std::cin.fail()) { // Comprobamos si hay errores de entrada
       std::cin.clear();
       std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Limpiamos el buffer manejado por la clase std::cin
   }

   std::cin >> nNumLetters;
} while(std::cin.fail());


La variable nNumLetters es de tipo int

Te aconsejo mirar el tema que publiqué hace poco sobre el funcionamiento del operador std::cin>> para una mejor comprensión del código.

http://foro.elhacker.net/programacion_cc/aporte_diagrama_de_flujo_del_operador_stdcin_stdistream-t443774.0.html

Hola hermano,
Pedia el numero y lo guardaba como string para poder verificar con la funcion "isdigit" si todos los caracteres de esa cadena son numeros. Y despues lo convierto de string a int y lo guardo en una variable tipo int para seguir trabajando con ese dato.

Hice esto porque no se como validar un int de que se han ingresado solo números, no me interesan caracteres ni otras cosas....

class_OpenGL

#3
Pero si te acabo de mostrar como validad que es un entero lo introducido :P

Esta es la secuencia:

1º- Mostramos el mensaje que nos pide el número
2º- Comprobamos que no hay errores de datos (es la parte del if)
    2.1º- En caso de error, limpiamos el buffer
3º- Pedimos datos, y empezamos el ciclo de nuevo si ha habido algún error (la condición del while)

Para comprender mejor como funciona la introducción de datos, te paso un tema mío donde lo explico con un diagrama de flujo:

http://foro.elhacker.net/programacion_cc/aporte_diagrama_de_flujo_del_operador_stdcin_stdistream-t443774.0.html

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL