Go Down

Topic: Ayuda con variables. [SOLUCIONADO POR NOTER] (Read 3091 times) previous topic - next topic

elricho

May 11, 2015, 12:28 am Last Edit: May 16, 2015, 04:20 pm by elricho
Tengo un rutina para guardar eventos en un array maximo 16 posiciones.
Code: [Select]
char* Eventos[16] ={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"};

Le puse valores para probarlo y bien arranco y La llamo asi

EventoNuevo("Prendi luces");   // o lo que sea


Y la funcion hace lo siguiente

Code: [Select]
void EventoNuevo( char* QuePaso )
{
    char HorayEvento[128];
    char* Hora = Reloj.Time();    
    for (int Bucle=1; Bucle<16; Bucle++)
    {
      Eventos[Bucle-1]=Eventos[Bucle];
    }
    strncpy(HorayEvento, Reloj.Time(), sizeof(HorayEvento));
    strncat(HorayEvento, QuePaso, (sizeof(HorayEvento) - strlen(HorayEvento)) );

    //Eventos[15]=HorayEvento;

    Eventos[15]=QuePaso;
}


El tema esta que de esa forma anda perfecto, pero yo necesito agregarle la hora delante por eso esta comentada la linea     Eventos[15]=HorayEvento;

Si bien HorayEvento me devuelve perfectamente la hora y el evento, no se x q motivo me pisa todos los valores anteriores, les muestro cuando arranca con 1 evento y despues de hacer 4 eventos me pisa siempre con el ultimo valor a todos los demas... muy raro, incluso le pone la misma hora y texto a los ultimos eventos, obviamente el problema debe estar en esos  strncpy y strncat porque lo encontre en internet si bien da el resultado no se que pasa que me hace fallar el array pisando los valores.





surbyte

Lo que quieres hacer es un log de alarmas.

y el código completo donde esta?
Leete las normas del foro asi verás que para ayudarte se debe entregar siempre la mejor información.

Pero mientras te consulto: pretendes crear un nombre de archivo con 18:44:19Protector como nombre?

Yo veo que tu rutina carga el evento al final de la FILO(First IN LAST OUT) y en cada paso la desplaza al punto anterior de la pila. Si tienes un error en el llamado a esta rutina, en cadapaso ira llenando la pila con el mismo valor.
Mira a ver si es por ahi.

elricho

#2
May 11, 2015, 01:49 am Last Edit: May 11, 2015, 01:57 am by elricho
No quiero crear ningun archivo ni nada, el nombre de la variable quedo porque lo saque de 1 ejemplo de google, ahora lo cambie asi se interpreta mejor.

Solo quiero guardar en 1 array el evento que paso y su hora delante en memoria nada mas.

Los llamo asi EventoNuevo("Prendi luces");   // o lo que sea

No veo forma que se produzca un error solo le paso un texto y la rutina lo que hace es desplaza y luego pone como ultimo valor del array el evento con la hora delante.
No se porque me hace lio ...

Sino uso esa variable HorayEvento funciona bien, pero claro necesito la hora

_jose_

Yo tampoco entiendo bien que es lo que quieres hacer ,pero por si quieres hacer por ejemplo un array de 16 eventos y cada evento tiene 16 caracteres (supongo...) no tendrias que hacer un array de dos dimensiones? Es decir un array de arrays :
char eventos[16][17];
Con esto crearias 16 arrays con 16 caracteres cada uno (he puesto 17 porque en los arrays de caracteres hay que dar un espacio mas para el simbolo de final de cadena).

surbyte

#4
May 11, 2015, 04:24 pm Last Edit: May 11, 2015, 04:35 pm by surbyte
esta usando punteros
Code: [Select]
char* Eventos[16] ={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"};

La definición char * es propia de punteros. Son 16 posiciones de longitud determinada por un \0 al final que le indica que hasta ahi ha llegado.

REPITO
Esa rutina debe funcionar solo cuando se produce un evento.
Si el evento tiene rebotes (tipico de Arduino por ejemplo) veras cosas como la que indicas.
Asegurate de que solo se ejecute una vez el evento.

elricho

Por ahi puede ser que este definiendo mal el array , el tema es que programo en varios lenguajes y a veces se me mezclan los codigos.

A ver si me explico mejor.

Algo asi haria en visual basic

Dim Eventos(16)

Y al ejecutar la rutina lo que pretendo es que se valla guardando en el array lo que paso max. 20 caracteres

entonces si se ejecuta 1 evento
en la ultima posicion quedaria

Eventos(16)="TIMER ON 14:24"

si pasa otro evento  mi array quedaria

Eventos(15)="TIMER ON 14:24"
Eventos(16)="Nuevo 17:24"

y asi susecivamente, me explico mejor ?

noter

¡¡Uuufff!!
Hay un par de cosillas que deberías tener en cuenta, aunque ahora me pillas sin tiempo.
Para empezar, como ya dijo surbyte, estás trabajando con punteros, pero que envíes un puntero a unos datos que habías escrito en determinada parte de la memoria, no significa que los datos a los que apunta sean los que has puesto ahí. En este caso, ten en cuenta que el array horayevento es local a la función, con lo que una vez se retorna de ella, en teoría la memoria que ocupaba ese array puede ser reutilizada. De hecho, si en lugar de volver a llamar a la misma función hubieras llamado a otra función que tenga sus variables locales probablemente te encontrarías con salidas más raras en tus eventos.
Debes replantear tu programa, por ejemplo partiendo como te dijo _jose_ de un array de caracteres de dos dimensiones (char array[16][20]) y escribiendo los datos en la memoria reservada a ese array. Puedes hacer un buffer circular: guardas en una variable el índice (0-15) del último elemento leído, y a medida que leas nuevos eventos, los escribes en el índice indicado y avanzas ese índice (cuando llegue a 16 será 0 de nuevo).

surbyte

Ya veo tu problema, que lo dijeron noter y jose tambien a su manera. Jose lo dijo ajustando el array y dando un líimte y noter refrezcó lo que te había dicho que si a un puntero no le dices el final lde ese string, entonces no sabe donde termina y empieza a hacer cosas locas.
Entonces

prueba esto
Code: [Select]
void EventoNuevo( char* QuePaso )
{
    char HorayEvento[128];
    char* Hora = Reloj.Time();   
    for (int Bucle=1; Bucle<16; Bucle++)
    {
      Eventos[Bucle-1]=Eventos[Bucle];
    }
    strncpy(HorayEvento, Reloj.Time(), sizeof(HorayEvento));
    strncat(HorayEvento, QuePaso, (sizeof(HorayEvento) - strlen(HorayEvento)) );

    //Eventos[15]=HorayEvento;

    Eventos[15]=QuePaso+'\0';
}

noter

Estoy esperando a ver si elricho lo ha probado ya, pero soy un poco escéptico con ese código, surbyte. Creo que pasará lo mismo que comenté respecto al original. Estás devolviendo punteros a datos que "han dejado de existir".

surbyte

Tu dices que no funciona con delimitar el puntero?

noter

No creo. Como dije, el problema es que vamos a ir asignando a cada puntero la misma ( o similar) dirección de memoria correspondiente a la zona de la pila donde se crean y luego se destruyen las variables locales de la función en cuestión.
¿Alguien ha probado o simulado el código?

surbyte

Que lo haga el interesado.

noter

Eso mismo esperaba yo por si, como creo, no funcionara, trazar las líneas del plan b; pero no me gusta predicar en el desierto,by parece que una vez más nos han dado plantón. >:(

elricho

#13
May 14, 2015, 08:20 pm Last Edit: May 14, 2015, 09:44 pm by elricho
Ahora pregunto algo sencillo, yo declare el array y le puse del 1 al 16 nros para probar la rutina y como ven en la pantalla despues de 4 eventos se desplazan los valores perfectamente, porque motivo al queres agregar un texto y hora hace esas cosas es lo que no entiendo.
Y el array lo declare al inicio del programa para que sea global y que se puede ver en todas las rutinas ... no se, no soy super experimentado en arduino, como dije programo en muchos lenguajes y por ahi aca le pifie en algo.

Hoy lo hago sin falta la prueba de surbite , he leido por ahi q se soluciono poniendo eso al final vemos.
Gracias por la ayuda !, y bien lo pruebo les digo.


elricho

Yo tampoco entiendo bien que es lo que quieres hacer ,pero por si quieres hacer por ejemplo un array de 16 eventos y cada evento tiene 16 caracteres (supongo...) no tendrias que hacer un array de dos dimensiones? Es decir un array de arrays :
char eventos[16][17];
Con esto crearias 16 arrays con 16 caracteres cada uno (he puesto 17 porque en los arrays de caracteres hay que dar un espacio mas para el simbolo de final de cadena).
Entiendo Jose lo que dices, pero para q crear dos dimensiones, si yo ya se que va a ir del 0 al 15 (16 posiciones) y dentro de ellas quiero poner 1 texto (evento y hora) y nada mas . Super sencillo pero me falla.

Go Up