PDA

Ver la versión completa : Se vuelve loco al leer un caracter incorrecto en c



smaug_
19-05-2008, 18:06
Puesto que esta tarde me aburro en el curro, me he propuesto hacer un pequeño tres en raya en c. De momento va bien la cosa, pero a la hora de leer desde teclado la posicion donde colocar la ficha, se me vuelve loco cuando no lee el caracter correcto.
Os explico como lo hago, el usuario tiene que introducir un numero del 1 al 9, dependiendo de donde quiera colocar la ficha. Por lo que tengo que controlar que no se inserte otro caracter o que este fuera de rango, ya que para calcular la posicion lo hago mediante operaciones. Os pongo el codigo y os explico el problema:



int comprueba(int n){
if(n<1 || n>9)
return 1;
else
return 0;
}
/***********************************/
do{
printf("introduce un numero: ");
scanf("%d",&n);
}while(comprueba(n)==1);
n--;
int fila=n/TAM_TAB;
int col=n%TAM_TAB;
tablero[fila][col]=UNO;
opciones[fila][col]=VACIO;


Bien, como veis, cojo un numero mediante scanf y en la funcion comprueba, simplemente mira que este dentro del rango, entonces si no lo esta,deberia de volver a pedir el numero. El caso esta en cuando meto una letra o caracter raro (.,- etc), en vez de volver a pedir el caracter, entra en un bucle infinito y muestra el mensaje de inserte un numero sin parar, sin llegar nunca ha volver a pedir el numero.
A que puede ser debido esto??

gondar_f
19-05-2008, 20:12
n<1 || n>9/QUOTE]
creo qeu te equivocaste con los signos de comparación, si pones
[QUOTE]n>1 || n<9
debería funcionarte

Un Saludo

Markitos1024
19-05-2008, 20:28
perdon no quiero contradecirlos pero seria

n>=1 && n<=9
osea 1< n <9 es el rango porque con el operador || el rango seria todos los mayores a 1 o menores a 9 pero 1000 cumple esa condicion.
y los operadores <= en vez de < ya que unos representan intervalos cerrados y otros abiertos..
saludos

PD: otro consejo si usas un compilador que usa C++ ya no uses scanf() ni print() usa flujos de datos cout << y cin >>
no recuerdo si scaf el numero 1 retorna 1 o su correspondiente en tabla ascci ten cuidado con los rangos

j8k6f4v9j
19-05-2008, 21:42
La comparación que puso en el códgo pegado originalmenete está bien. El problema no está ahí.

Las expresiones son equivalentes:

( ! ( n < 1 || n > 9 ) ) == ( n >=1 && n <= 9 )

Está aquí:
}while(comprueba(n)==1);

debes cambiarlo por esto:


}while ( ( comprueba(n) ) ==1 );

Salu2



http://img359.imageshack.us/img359/6631/celliigy4.pngKeep on Rollin' :mad:

gondar_f
19-05-2008, 23:55
perdon no quiero contradecirlos pero seria

Código:
n>=1 && n<=9osea 1< n <9 es el rango porque con el operador || el rango seria todos los mayores a 1 o menores a 9 pero 1000 cumple esa condicion.
y los operadores <= en vez de < ya que unos representan intervalos cerrados y otros abiertos..

tienes razón, aun así para coger todo el rango la respuesta sería:
n>0 && n<10
me había fijado en los operadores de comparación, pero no en el operador lógico


debes cambiarlo por esto:


Código:
}while ( ( comprueba(n) ) ==1 );
no es necesario ese parentesis, la llamada a una función es une elemento unitario, ese parentesis sería igual a:
((a)==5)
que no es necesario...

Además en este caso no sería necesario hacer la comparación (OJO esto no fuenciona en todos los compiladores y solo es 100% correcto segun el C de K&R, en cristiano pre ANSI C, aun así suele seguir funcionando):

}while(comprueba(n));
ya que el 0 es lo que denota falso y un número distinto es verdadero, de ahí que se puedan hacer en algunos compiladores cosas como esta:

for(;;) {
//instrucciones
}

o esta otra:

while(1) {
//instruccione
}

Un Saludo

j8k6f4v9j
20-05-2008, 01:50
no es necesario ese parentesis, la llamada a una función es une elemento unitario, ese parentesis sería igual a:
((a)==5)
que no es necesario...

Juas, es verdad, me he confundido con cuando hay una asignación de por medio:


}while ( ( resultado = comprueba(n) ) == 1 );ahí sí haría falta el paréntesis para comparar resultado con 1


Salu2



http://img359.imageshack.us/img359/6631/celliigy4.pngKeep on Rollin' :mad:

Markitos1024
20-05-2008, 03:00
Las expresiones son equivalentes:

( ! ( n < 1 || n > 9 ) ) == ( n >=1 && n <= 9 )


debes cambiarlo por esto:



Si si, famosa ley de morgan:D

smaug_
20-05-2008, 09:37
Gracias por la ayuda chicos. Las comprobaciones logicas estan bien, tened en cuenta que primero compruebo el caso falso y si no es falsto, tonces esta dentro del rango. Siempre he sido raro con las comprobaciones logicas, pienso al reves.
Ya he solucionado el problema, al final, le he "robado" dos funciones que hizo j8 y dejo en un post, el codigo quedaria mas o menos de la siguiente forma:



/************************************************** **************************/


void lee_cad (char *cadena) {
fgets(cadena,TAM_CAD,stdin);
cadena[(strlen(cadena))-1] = '\0';
}

long lee_int () {
long int i;
char cadena[TAM_CAD],sobra[TAM_CAD];

lee_cad(cadena);
i=strtol(cadena, (char **)sobra, 10);
return i;
}
/************************************************** **************************/
do{

do{
printf("introduce un numero: ");
n=lee_int();
}while(comprueba(n));
n--;
int fila=n/TAM_TAB;
int col=n%TAM_TAB;
tablero[fila][col]=player;
opciones[fila][col]=VACIO;
// Imprimimos resultado
imprime();
cambiaEstado();
}while(compruebaTablero()==VACIO);