PDA

Ver la versión completa : Necesito ayuda con string, me estoy volviendo loco



Puck2099
08/08/2004, 19:57
Hola,

Bueno, tenía programados ya unos temporizadores para mi juego Samurai y en el "emulador" del VC++ va perfecto, pero lo compilo para la GP32 y me hace una cosa muy rara:

Donde tenía que mostrarse un String de 4 caracteres solo muestra los dos primeros (en el VC++ ya digo que lo hace bien) y no sé a qué se debe...

Os pego los trozos de código implicados en el asunto:



void Mostrar_Reloj (int tiempo, int timer, char reloj[4]) {
int minutos;
int segundos;
char seg_resto[2];
char min_resto[1];
minutos = timer / 60;
segundos = timer - minutos*60;
if (60 - segundos < 10) {
seg_resto[0] = '0';
switch (60-segundos) {
case 0:
seg_resto[1] = '0';
break;
case 1:
seg_resto[1] = '1';
break;
case 2:
seg_resto[1] = '2';
break;
case 3:
seg_resto[1] = '3';
break;
case 4:
seg_resto[1] = '4';
break;
case 5:
seg_resto[1] = '5';
break;
case 6:
seg_resto[1] = '6';
break;
case 7:
seg_resto[1] = '7';
break;
case 8:
seg_resto[1] = '8';
break;
case 9:
seg_resto[1] = '9';
break;
}
}
else if (60 - segundos == 60) {
seg_resto[0] = '0';
seg_resto[1] = '0';
}
else {
sprintf(seg_resto, "%d", 60-segundos);
}
if (segundos >0) {
sprintf(min_resto, "%d", tiempo-minutos-1);
}
else {
sprintf(min_resto, "%d", tiempo-minutos);
}
reloj[0] = min_resto[0];
reloj[1] = ':';
reloj[2] = seg_resto[0];
reloj[3] = seg_resto[1];
}


Se supone que lo que hace esa función es, a partir de un tiempo base (tiempo) y un temporizador (timer) hacer una especie de reloj metido en la string que también se le pasa como argumento.



Mostrar_Reloj (tiempo, temp1, cadena);
GpTextOut(NULL, &gpDraw[nflip], 260, 11, cadena, 0xC0);


Y esto tiene que mostrar el resultado de lo anterior en una posición específica de la pantalla.

Como digo, lo que muestra finalmente en la GP32 son los dos primeros caracteres de la string, es decir, el minuto y los dos puntos.

A lo mejor estoy obcecado con el código y no veo algo evidente, pero es que me está volviendo loco y por más que pruebo cosas no consigo arreglarlo.

A ver si arreglo esto y saco esta nueva versión a la luz...

Muchas gracias por la ayuda.

Wave
08/08/2004, 20:13
Yo de ti haria dos cosas, una inicializar
seg_resto[0] y seg_resto[1] a '0' y otra hacer que reloj sea de 5 caracteres y el ultimo lo igualas a 0, sin comillas (final de cadena).
Otra cosa que puedes hacer es en vez de un case gigante meter:
Como los codigos ascii del 0 al 9 son del 30 al 39 respectivamente.
seg_resto[1]=(60-segundos) + 30;
En vez del switch.

Puck2099
08/08/2004, 20:16
Voy a probarlo, muchas gracias Wave :)

Saludos

Puck2099
08/08/2004, 20:27
Nada, he hecho las modificaciones que me decías y sigue igual...

El problema es de la función Mostrar_Reloj, pues si antes de mostrar la string en pantalla la modifico posición por posición sí que se muestra correctamente con los valores que le meta en ese momento...

Saludos

theNestruo
08/08/2004, 22:05
Escrito originalmente por Wave
Como los codigos ascii del 0 al 9 son del 30 al 39 respectivamente.
seg_resto[1]=(60-segundos) + 30;

Er... esos códigos son en numeración hexadecimal; el fragmento de código correcto sería, por lo tanto:

seg_resto[1]=(60-segundos) + 0x30; /* Fijate en el 0x */
O utilizando los códigos ASCII correctos (del 48 -0- al 57 -9-):

seg_resto[1]=(60-segundos) + 48;
Aunque yo pienso que la forma más cómoda de hacerlo es la siguiente:

seg_resto[1]='0' + 60 - segundos;

Aún así, no entiendo porqué hacer tanta especialización. El siguiente código vale para cualquier valor de segundos entre 0 y 60:

sprintf(seg_resto, "%02d", 60-segundos);
/* El 2 para que sean usados dos caracteres,
y el 0 para que rellene con ceros los huecos que sobren */

Aunque ya puestos a simplificar la función... vamos también a corregirla: el parámetro reloj tiene que tener al menos 5 caracteres -4 para el texto y 1 para el "\n" final- aunque la mejor opción es no especificar su longitud.


void Mostrar_Reloj (int tiempo, int timer, char *reloj) {
int minutos, segundos;

timer=(tiempo * 60)-timer;
segundos=timer % 60;
minutos=(timer - segundos) / 60;

sprintf (reloj, "%1d:%02d", minutos, segundos);
}

Optimizando un poco (posiblemente innecesario, peeero...):


void Mostrar_Reloj (int tiempo, int timer, char *reloj) {
static int segundos;
/* Con el modificador static para aligerar el trabajo con el stack,
si esta función es llamada muy a menudo */

timer=(tiempo * 60)-timer;
segundos=timer % 60;

sprintf (reloj, "%1d:%02d", (timer - segundos) / 60, segundos);
}

Consejo: que tiempo se especifique en segundos, y te ahorras una multiplicación cada vez que llames a esta función.

Si te funciona dímelo :) . Si no te funciona, dímelo también que veamos dónde está el problema, ¿ok? :) .
¡Un saludo!

Edit: No me había dado cuenta de que son 60 - segundos, y no segundos, lo que hay que mostrar.

Puck2099
08/08/2004, 22:17
Gracias por la ayuda theNestruo, mañana lo pruebo y te digo que ahora me voy a la cama.

Hasta mañana.

Puck2099
09/08/2004, 09:27
theNestruo, ya he probado tu función y funciona perfectamente :) :) :)

Muchísimas gracias, ahora a dar unos retoques y sacar a la luz la próxima versión :D