Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Ayuda con un pedacito de codigo! Por favor! (https://www.clubdelphi.com/foros/showthread.php?t=80048)

m1kevil 31-08-2012 06:42:57

Ayuda con un pedacito de codigo! Por favor!
 
Código:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int TirarDados (void);
int CantJugadores (void);
int transEntero(char);
int Jugadores;



int main () {
   
   
    srand (time(NULL));
   
    printf("!Bienvenidos al juego: EL PRESO!\n\n");
   
    Jugadores = CantJugadores();



system("pause");
return EXIT_SUCCESS;

    }


// Funcion para tirar los dados // 
int TirarDados (void)
{   
    Dados = rand() % 11+2;
    printf("Arrojas los dados. Has sacado %d! \n", Dados);
   
    return Dados;


// Funcion para pasar de char a entero //
int transEntero(char s)
{
    return s - '0';
}

// Funcion para validar la cantidad de jugadores al principio del juego//
int CantJugadores ()
{
    printf("Ingrese la cantidad de jugadores (Minimo 2, Maximo 5): ");
    char jugador = getchar();
    int Jugadores = transEntero(jugador);
    while (Jugadores < 2 || Jugadores > 5)
    {
    printf("Ingrese una cantidad de jugadores valida: \n");
    char jugador = getchar();
    int Jugadores = transEntero(jugador);
    }
    printf("Los participantes del juego seran %d.\n", Jugadores);
    return Jugadores;   
}

El tema es asi, estoy empezando a codificar la primer parte de un juego para un proyecto de la universidad. Me encontre con un problema cuando quiero validar la cantidad de jugadores que van a ingresar por teclado. Tengo que validar que sea un valor entre 2 y 5 Jugadores, y a su vez que el programa no aborte ni pinche cuando se ingrese una letra o un caracter distinto de un decimal.
La primera parte va bien pero si se cumple la condicion del while, es decir se ingresa algo que no va entre 2 y 5, luego el programa pide nuevamente ingresador una cantidad de jugadores valida... y por mas que se ponga un 2, 3, 4 o 5, el programa no responde bien y vuelve a pedir una cantidad de jugadores valida...
Por favor alguien que me ayude a darme cuenta del error!

Saludos!!

escafandra 31-08-2012 08:39:39

Mira esta adaptación:
Código:

#include <conio.h>

int CantJugadores ()
{
  int Jugadores;
  do{
    printf("Ingrese una cantidad de jugadores valida (2 a 5): ");
    Jugadores = transEntero(getche());
    printf("\n");
  }while (Jugadores < 2 || Jugadores > 5);

  printf("Los participantes del juego seran %d.\n", Jugadores);
  return Jugadores;
}

PD: Pon las etiquetas de código, se entenderá mejor :)


Saludos.

m1kevil 31-08-2012 08:54:37

Muchisimas gracias escafandra! Funciona bien! Hace lo que necesito.. pero me muestra los mensajes del printf por duplicado, ya sea si pongo un numero valido o no valido me muestra 2 veces por pantalla cada mensaje.. sabes a que puede deberse?


Por otro lado, cual es la diferencia entre getche y getchar? Muchas gracias por tu ayuda!!


PERDON! EDIT >>>> Ya me di cuenta solo... le daba enter despues de ingresar el digito por teclado, y getche se hace el echo por pantalla sin necesidad de apretar enter. Muy bueno! GRACIAS!

Podrias ayudarme con lo ultimo? si necesitara verificar numeros de mas de 2 digitos, ya sea entre 50 y 200 por ejemplo, podria usar lo mismo? o tendria problemas al ingresar una letra 'a' por ej: me daria el numero entero 97 ???
Por ejemplo ingrese una 'l' y me dio el numero 60 :(


Muchas gracias!

Casimiro Notevi 31-08-2012 09:51:07

Cita:

Empezado por m1kevil (Mensaje 441330)
...

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración :)

Recuerda poner los tags al código fuente, ejemplo:



Gracias :)

escafandra 31-08-2012 10:48:07

Cita:

Empezado por m1kevil (Mensaje 441330)
...si necesitara verificar numeros de mas de 2 digitos, ya sea entre 50 y 200 por ejemplo, podria usar lo mismo?

Mejor estudia la función atoi.

Saludos.

m1kevil 31-08-2012 19:04:41

Le voy a echar un vistazo, muchas gracias por su ayuda! Perdon por lo de los tags, no lo había visto.


Saludos!

m1kevil 31-08-2012 19:51:33

Código:

// Funcion para elegir la maxima puntuacion al ppio del juego //
int ElegirPuntuacion ()
{
    char buffer [256];
    do
    {
    printf("Ingrese la cantidad de presos que se permiten dejar escapar (50 a 200): ");
    fgets (buffer, 256, stdin);
    PuntuacionMax = atoi (buffer);
    }
    while (PuntuacionMax < 50 || PuntuacionMax > 200);
    printf("No podran escaparse mas de %d presos. Si esto ocurre, el jugador pierde. A Jugar! \n", PuntuacionMax);
    return PuntuacionMax; 
}

Aquí les pego el código que logré con la funcion atoi. Muchas gracias a todos funciona de maravilla.. y de paso voy aprendiendome las reglas del foro!


Saludos!! Pueden cerrar el thread si quieren!

ecfisa 31-08-2012 20:24:02

Hola m1kevil.

Gracias por acercarnos el resultado :).

Aprovecho para comentarte que en este caso es suficiente
Código:

...
  char buffer[4];
  do {
    fgets(buffer, 4, stdin);
  ...

ya que el valor máximo permitido nunca superará las tres cifras.

Saludos.

m1kevil 31-08-2012 20:37:27

Es cierto. Gracias por tu aporte! Pero de todos modos prefiero dejar los 256, ya que si introducen una cadena de caracteres demasiado larga, no se produce ningun error. Es decir, la toma por stdin correctamente, y como no es un numero valido da 1 solo mensaje de error.
Me ha pasado de que cambiando el valor a 4 e introduciendo una cadena de caracteres demasiado larga, se repiten varias veces los mensajes.
Es complicado de explicar.. corriendo el programa entenderas lo que digo. Muchas gracias de todas formas!

m1kevil 31-08-2012 22:20:43

Código:

// Funcion para definir nombres de los jugadores y quien empieza primero //
int TurnoInicial (int Jugadores)
{
    char vec[Jugadores];
    int i;   
    for (i=0; i<Jugadores; i++)
    {
            printf("Ingrese el nombre del jugador %d: ", i+1);
            scanf ("%s", &vec[i]);
    }
    for (i=0; i<Jugadores; i++)
    {
            printf("El jugador %d se llama: %s\n", i+1, vec[i]); 
    }
   
}


Bueno, siguiendo con este juego y los problemas... ahora necesito que luego de determinar la cantidad de jugadores que participaran del juego, una funcion sea capaz de almacenar los nombres de los jugadores (ingresados por teclado), y guardalos en un vector de la cantidad de posiciones de la variable 'Jugadores'.
Este vector será utilizado luego para desplegar el nombre del jugador en el momento que le toque su turno de tirar los dados por ejemplo.

Con el código expuesto arriba, funciona bien hasta que ingreso el ultimo nombre por teclado. Luego el programa se cuelga. Pienso que el problema radica en la funcion scanf y en el %s . Quizas otro método de entrada para los strings funcione mejor en este caso, pero es la primera vez que manejo cadenas de caracteres en C.

Por favor agradecería que me dieran una mano!
Desde ya muchas gracias!

escafandra 01-09-2012 20:22:54

Tu código tal como lo expones no puede compilar puedes definir un array estático de un tamaño definido por una variable.

Una primera aproximación a tu problema sería definir un array de dos dimensiones, una para el número máximo de jugadores admitidos y otra para el tamaño de los nombres. Si ese array lo defines como variable global lo conocerán todas las funciones de tu juego.

Este sería el ejemplo descrito:

Código:

char Nombres[5][41];  // Cinco jugadores 40 caracteres por nombre (mas el nulo final)

int TurnoInicial (int Jugadores)
{
  int i;
  char Buffer[1024];  // Buffer para la entrada por teclado.
 
  for(i = 0; i < Jugadores; i++){
    printf("Ingrese el nombre del jugador %d: ", i+1);
    strncpy(Nombres[i], gets(Buffer), 40);  // aseguramos que no entran mas de 40 caracteres
  }
  for(i = 0; i < Jugadores; i++){
    printf("El jugador %d se llama: %s\n", i+1, Nombres[i]);
  }
}

Saludos.

m1kevil 01-09-2012 20:51:02

No sabes como te agradezco la ayuda Escafandra! Me estaba pelando las pestañas! Funciona de maravilla!!!

Código:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <time.h>

int tirarDados (void);
int transEntero (char);
int cantJugadores (void);
int elegirPuntuacion (void);
char ingresarNombres (int);
int Dados, Jugadores, puntuacionMax;


int main () {
   
    char Nombres[Jugadores][40];
   
    srand (time(NULL));
   
    printf("!Bienvenidos al juego: EL PRESO!\n\n");
   
    Jugadores = cantJugadores();
    puntuacionMax = elegirPuntuacion();
    Nombres[Jugadores][40] = ingresarNombres(Jugadores);
   
    tirarDados();
   
   
system("pause");
return EXIT_SUCCESS;

    }
   
   
// Funcion para tirar los dados // 
int tirarDados (void)
{   
    Dados = rand() % 11+2;
    printf("Arrojas los dados. Has sacado %d! \n", Dados);
   
    return Dados;


// Funcion para pasar de char a entero //
int transEntero(char s)
{
return s - '0';
}

// Funcion para validar la cantidad de jugadores al principio del juego//
int cantJugadores ()
{
    do
    {
    printf("Ingrese la cantidad de jugadores (2 a 5): ");
    Jugadores = transEntero(getche());
    printf("\n");
    } while (Jugadores < 2 || Jugadores > 5);
   
    printf("Los participantes del juego seran %d.\n\n", Jugadores);
    return Jugadores;   
}

// Funcion para elegir la maxima puntuacion al ppio del juego //
int elegirPuntuacion ()
{
    char buffer [256];
    do
    {
    printf("Determine la cantidad de presos que se permiten dejar escapar (50 a 200): ");
    fgets (buffer, 256, stdin);
    puntuacionMax = atoi (buffer);
    } while(puntuacionMax < 50 || puntuacionMax > 200);
 
    printf("No podran escaparse mas de %d presos. Si esto ocurre, el jugador pierde. A Jugar!!! \n\n", puntuacionMax);
    return puntuacionMax;
}

// Funcion para definir nombres de los jugadores //
char ingresarNombres (int Jugadores)
{
  int i;
  char Nombres[Jugadores][40];
  char Buffer[1024];  // Buffer para la entrada por teclado.
  for(i = 0; i < Jugadores; i++)
  {
    printf("Ingrese el nombre del jugador %d: ", i+1);
    strncpy(Nombres[i], gets(Buffer), 40);  // aseguramos que no entran mas de 40 caracteres
  }
  for(i = 0; i < Jugadores; i++)
  {
    printf("El jugador %d se llama: %s\n", i+1, Nombres[i]);
  }
  return Nombres[Jugadores][40];
}

Ahí está como va quedando todo el código. Tuve un problema al declarar la variable char Nombres[Jugadores][40] globalmente... me tira un error el compilador diciendo: "variable-size type declared outside of any function" , lo cual es logico, pero justamente debería pasar eso.. :S Asique tuve que declararla en el main y en la funcion.
Por favor avisame si tienes alguna solución para ese pequeño problema. Desde ya muchas gracias por tu tiempo, es justo lo que necesitaba.

Es un gran avance para mi.. ahora tengo que planear mejor en lapiz y papel la lógica del juego.

escafandra 01-09-2012 22:22:50

Cita:

Empezado por m1kevil (Mensaje 441474)
Tuve un problema al declarar la variable char Nombres[Jugadores][40] globalmente... me tira un error el compilador diciendo: "variable-size type declared outside of any function" , lo cual es logico, pero justamente debería pasar eso.. :S Asique tuve que declararla en el main y en la funcion.

Ya te expliqué que no puedes declarar arrays estáticos dando el tamaño en una variable, debe ser una constante. Un array no puede tomar un valor así como así. En C un array es un puntero al primer elemento. Si tienes un array declarado como estático, no puede tomar otro valor. Lo podrá tomar un puntero char** (puntero a puntero) al ser de dos dimensiones. Pero creo que esto, de momento no lo vas a entender.

Para los valores constantes en toda la aplicación es mejor definirlos al principio, así los puedes cambiar fácilmente si es necesario.

Mira esta adaptación de tu programa, en la que he modificado también la anterior función ingresarNombres para hacerla mas segura contra el desbordamiento de buffer:

Código:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <time.h>

#define MIN_JUGADORES  2
#define MAX_JUGADORES  5
#define MIN_PUNTUACION 50
#define MAX_PUNTUACION 200
#define MAX_NOMBRE    40

char Nombres[MAX_JUGADORES][MAX_NOMBRE + 1];

int  tirarDados (void);
int  transEntero (char);
int  cantJugadores (void);
int  elegirPuntuacion (void);
void ingresarNombres (int);
int  Dados, Jugadores, puntuacionMax;

int main(int argc, char* argv[])
{
  srand (time(NULL));

  printf("!Bienvenidos al juego: EL PRESO!\n\n");

  Jugadores = cantJugadores();
  puntuacionMax = elegirPuntuacion();
  ingresarNombres(Jugadores);
  tirarDados();
  system("pause");
  return EXIT_SUCCESS;
}

// Funcion para tirar los dados // 
int tirarDados (void)
{   
  Dados = rand() % 11+2;
  printf("Arrojas los dados. Has sacado %d! \n", Dados);
  return Dados;
}

// Funcion para pasar de char a entero //
int transEntero(char s)
{
  return s - '0';
}

// Funcion para validar la cantidad de jugadores al principio del juego//
int cantJugadores ()
{
  do{
    printf("Ingrese la cantidad de jugadores (%d a %d): ", MIN_JUGADORES, MAX_JUGADORES);
    Jugadores = transEntero(getche());
    printf("\n");
  }while (Jugadores < MIN_JUGADORES || Jugadores > MAX_JUGADORES);

  printf("Los participantes del juego seran %d.\n\n", Jugadores);
  return Jugadores;
}

// Funcion para elegir la maxima puntuacion al ppio del juego //
int elegirPuntuacion ()
{
  char buffer [256];
  do{
    printf("Determine la cantidad de presos que se permiten dejar escapar (50 a 200): ");
    fgets (buffer, 256, stdin);
    puntuacionMax = atoi(buffer);
  } while(puntuacionMax < MIN_PUNTUACION || puntuacionMax > MAX_PUNTUACION);

  printf("No podran escaparse mas de %d presos. Si esto ocurre, el jugador pierde. A Jugar!!! \n\n", puntuacionMax);
  return puntuacionMax;
}

// Funcion para definir nombres de los jugadores //
void ingresarNombres (int Jugadores)
{
  int i, n;
  for(i = 0; i < Jugadores; i++){
    printf("Ingrese el nombre del jugador %d: ", i+1);
    n = strlen(fgets(Nombres[i], MAX_NOMBRE, stdin))-1;
    if(Nombres[i][n] == '\n') Nombres[i][n] = 0;
  }
  for(i = 0; i < Jugadores; i++){
    printf("El jugador %d se llama: %s\n", i+1, Nombres[i]);
  }
}

Cita:

Empezado por m1kevil (Mensaje 441474)
Es un gran avance para mi.. ahora tengo que planear mejor en lapiz y papel la lógica del juego.

Eso es fundamental.


Saludos.


La franja horaria es GMT +2. Ahora son las 01:14:21.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi