Ayuda con variables. [SOLUCIONADO POR NOTER]

Tengo un rutina para guardar eventos en un array maximo 16 posiciones.

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

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.

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.

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

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).

esta usando punteros

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.

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 ?

¡¡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).

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

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';
}

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".

Tu dices que no funciona con delimitar el puntero?

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?

Que lo haga el interesado.

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. >:(

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.

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).

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.

Digo yo porque la gente no pondrá las librerías que usa y sus codigos completos.

Resulta que quiero probarlo y errores porque lalibrería RTC que usa es distinta.

Bueno amigos, no funciona hace lo mismo, pero bueno la voy a seguir peleando cuando encuentre la solucion se los paso.

Pero aclaro solo falla cuando quiero usar la variable que contiene la hora + evento, si uso el evento solo funciona perfecto !

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;   si uso esa variable falla pisando los ult. valores con los miso

    Eventos[15]=QuePaso;  // asi funciona perfecto pero no tiene la hora
}

Gracias igual.

¿Seguro que te funciona si sólo asignas el evento? No he visto tu código completo (no lo has puesto), pero supongo que es gracias a que has predefinido las cadenas de los eventos que vas a asignar en variables separadas. Entonces, tu función devuelve respectivamente las cadenas con las que has llamado a la propia función, no la cadena local de la función horayevento. El procedimiento para conseguir lo que estás intentando, sería definir el espacio global para los 16 eventos, y en la función escribir en ese espacio, en lugar de en uno local de dicha función.

Lo defini el array antes del setup por lo que entiendo es global sino corregime. Si quieren hago un programita chiquito ya que son miles de linea y no veo el sentido en postear miles de cosas cuando el problema es tan localizado como lo que les cuento, pero si quieren hago.

El codigo es tan sencillo como lo q mostre no hay mas que eso, una array definido, cuando pasa algo en una rutina lo llamo de la forma que mostre y la rutina mueve los valores mas viejos para arriba, y al ultima posicion del array le asigna el nuevo evento.

Tambien puedo hacer 1 videito corto para que veas como al apretar distintos botones sin usar el campo hora funciona de maravilla, si le agrega la hora chau.

Avisame que preferis y lo hago.

Fijate esto para que veas combinando eventos con y sin hora lo que pasa.
Notas que si bien los textos de los eventos son correctos le pone a todos la misma hora.