Autor Tema: Tutorial - Cadenas y arreglos de chars  (Leído 68973 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #75 en: 07 de Febrero de 2013, 18:19:22 »
Jaja, tu mente es perversa  :D :D

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #76 en: 08 de Febrero de 2013, 01:21:30 »
Quería agradecer por el magnífico tutorial, me la pasé varias horas (sino días) tratando de averiguar de donde venia el 'error' de no poder asignarle valores a una matriz char (en la que almaceno datos para un menú) una vez ya en la mitad del programa... Y eso pasa cuando en la facultad te dicen que estas programando en C (y en realidad es el C++) sumandose a eso algunas incongruencias o cositas raras que suele hacer el amigo CCS  :D

Pregunto: ¿Hay alguna forma mas correcta o elegante de hacer esto?:

Código: [Seleccionar]
char opc_menu[7][15]={"Estado","Tipo de onda","Amplitud","Frecuencia","Periodo","Duty cicle","Apagar"};
----------
char opc_onda[7][15]={"Rampa","Triangular","Cuadrada","Senoidal","Atras","",""};
for(i=0;i<=7;i++)
{
     strcpy(opc_menu[i],opc_onda[i]);
}

Hola :)

Sí, te propongo ésta:

Código: [Seleccionar]
#include "string.h"
memcpy(opc_menu, opc_onda, 7*15);

Copia 7*15 bytes desde el apuntador opc_onda hacia el apuntador opc_menu.

Es raro lo que pides porque perderías lo que había en opc_menu y si es un microcontrolador, también estarías desperdiciando un poquito de ROM  ;-)

Te sugiero esto...

Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int menu;
    int opcion;
       const char strings[2][7][15] =
   {
         {"Estado", "Tipo de onda", "Amplitud", "Frecuencia", "Periodo", "Duty cicle", "Apagar"}, //Accede aquí con menu
         {"Rampa", "Triangular", "Cuadrada", "Senoidal", "Atras", "", ""} //Y acá con opción
   };
  
      for(menu = 0; menu < 2; ++menu)
         for(opcion = 0; opcion < 7; ++opcion)
             printf("\"%s\"\n", &strings[menu][opcion][0]);
  
  system("PAUSE");
  return 0;
}

Y obtendrás esto...

http://img705.imageshack.us/img705/1876/strdh.png



Saludos a todos :D
« Última modificación: 08 de Febrero de 2013, 01:25:25 por migsantiago »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #77 en: 08 de Febrero de 2013, 01:57:11 »
Un poco más de... pero ahora con unas macrillos :D

Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE_AR(type, object) (sizeof(type) * sizeof(object))
#define MAX_ELEMS_PER_LIST    (7)
#define MAX_CHARS_PER_STRING  (15)

int main(int argc, char *argv[])
{
   const char strings[][MAX_ELEMS_PER_LIST][MAX_CHARS_PER_STRING] =
   {
      {"Estado", "Tipo de onda", "Amplitud", "Frecuencia", "Periodo", "Duty cycle", "Apagar"},
      {"Rampa", "Triangular", "Cuadrada", "Senoidal", "Atras", "", ""}
   };
   
   char opc_menu[][MAX_CHARS_PER_STRING]={"Estado", "Tipo de onda", "Amplitud", "Frecuencia", "Periodo", "Duty cycle", "Apagar"};
   char opc_onda[][MAX_CHARS_PER_STRING]={"Rampa", "Triangular", "Cuadrada", "Senoidal", "Atras", "", ""};

   int menu;
   int opcion;

   for(menu = 0; menu < (SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST); ++menu)
      for(opcion = 0; opcion < MAX_ELEMS_PER_LIST; ++opcion)
         printf("\"%s\"\n", &strings[menu][opcion][0]);

   printf("\n");

   memcpy(opc_menu, opc_onda, SIZE_AR(char, opc_onda));
   
   for(opcion = 0; opcion < (SIZE_AR(char, opc_menu) / MAX_CHARS_PER_STRING); ++opcion)
      printf("\"%s\"\n", &opc_menu[opcion][0]);

   printf("\n");

   printf("Tamanio de opc_menu en bytes [%u]\n", SIZE_AR(char, opc_menu));
   printf("Tamanio de opc_onda en bytes [%u]\n", SIZE_AR(char, opc_onda));
   printf("Tamanio de strings en bytes [%u]\n", SIZE_AR(char, strings));

   printf("\n");

   printf("Tamanio de strings[x] en elementos [%u]\n", (SIZE_AR(char, strings) / MAX_ELEMS_PER_LIST / MAX_CHARS_PER_STRING));
   printf("Tamanio de strings[][x] en elementos [%u]\n", MAX_ELEMS_PER_LIST);
   printf("Tamanio de opc_menu[] en elementos [%u]\n", (SIZE_AR(char, opc_menu) / MAX_CHARS_PER_STRING));

   system("PAUSE");
   return 0;
}

Y el resultado...

Código: [Seleccionar]
"Estado"
"Tipo de onda"
"Amplitud"
"Frecuencia"
"Periodo"
"Duty cycle"
"Apagar"
"Rampa"
"Triangular"
"Cuadrada"
"Senoidal"
"Atras"
""
""

"Rampa"
"Triangular"
"Cuadrada"
"Senoidal"
"Atras"
""
""

Tamanio de opc_menu en bytes [105]
Tamanio de opc_onda en bytes [105]
Tamanio de strings en bytes [210]

Tamanio de strings[x] en elementos [2]
Tamanio de strings[][x] en elementos [7]
Tamanio de opc_menu[] en elementos [7]
Presione una tecla para continuar . . .
« Última modificación: 08 de Febrero de 2013, 02:01:40 por migsantiago »

Desconectado matyvico

  • PIC10
  • *
  • Mensajes: 20
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #78 en: 08 de Febrero de 2013, 12:43:31 »

Hola :)

Sí, te propongo ésta:

Código: [Seleccionar]
#include "string.h"
memcpy(opc_menu, opc_onda, 7*15);

Copia 7*15 bytes desde el apuntador opc_onda hacia el apuntador opc_menu.

Es raro lo que pides porque perderías lo que había en opc_menu y si es un microcontrolador, también estarías desperdiciando un poquito de ROM  ;-)

Te sugiero esto...

Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int menu;
    int opcion;
       const char strings[2][7][15] =
   {
         {"Estado", "Tipo de onda", "Amplitud", "Frecuencia", "Periodo", "Duty cicle", "Apagar"}, //Accede aquí con menu
         {"Rampa", "Triangular", "Cuadrada", "Senoidal", "Atras", "", ""} //Y acá con opción
   };
  
      for(menu = 0; menu < 2; ++menu)
         for(opcion = 0; opcion < 7; ++opcion)
             printf("\"%s\"\n", &strings[menu][opcion][0]);
  
  system("PAUSE");
  return 0;
}

Muchas gracias por la respuesta y por los ejemplos!

Te respondo: Había pensado en hacer un arreglo tipo "matriz" donde se contuvieran todas las opciones de todos lo menúes posibles de todo el programa, supongo que deje de tener en cuenta esa opción por algún problema que me habrá surgido y lo hice de la forma que preguntaba antes (copiando el contenido de un arreglo char local en uno global). Un motivo por el que lo hice así es porque (yo suponía) de esa manera ocupo memoria solo para el char global, y durante solo un momento (mientras llamo alguna función particular con menú propio) ocupo memoria también por el char local que luego se libera. También lo hacía de esa forma ya que en la función que me genera el menú en el LCD a partir de el arreglo opc_menu utilizo justamente ese nombre, es decir llamo en particular a ese arreglo de forma general y es ese arreglo el que deberá cambiar en cada caso si es que se quiere mostrar un menú diferente, de ahí que copiara el contenido de cualquier otro arreglo char como opc_onda en opc_menu. No se si soy muy claro, lo que si tengo presente es que cada vez me doy mas cuenta que en la facultad me han estafado/engañado a mas no poder :5] para que tengan una idea (sin agrandarme ni mucho menos) yo, dentro de mi grupo de compañeros, soy uno de los mas "capaces/inteligentes" en cuestiones de programación, así que imaginen  :roll:

Desconectado matyvico

  • PIC10
  • *
  • Mensajes: 20
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #79 en: 08 de Febrero de 2013, 13:08:06 »
Yo se que voy a ganar mas de un enemigo por hacer tantas preguntas  :D pero es que les juro que estoy desesperado viendo la forma de resolver esto (además mientras pueda aprender algo nuevo voy a tratar de esforzarme al menos!  ;-))

No termino de entender bien que se hace con estas lineas de código en particular:

Código: [Seleccionar]
#define SIZE_AR(type, object) (sizeof(type) * sizeof(object))
Código: [Seleccionar]
for(menu = 0; menu < (SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST); ++menu)
Código: [Seleccionar]
memcpy(opc_menu, opc_onda, SIZE_AR(char, opc_onda));  
Código: [Seleccionar]
for(opcion = 0; opcion < (SIZE_AR(char, opc_menu) / MAX_CHARS_PER_STRING); ++opcion)
En realidad lo que mas me llama la atención y no lo entiendo porque nunca lo vi es esa definición de los "argumentos" (no se si llamarlos así) de "SIZE_AR" y que luego pueden ser reemplazados luego de la barra '/' por otras definiciones...

Muchísimas gracias por adelantado! Espero desburrarme un poco  :D
« Última modificación: 08 de Febrero de 2013, 15:45:13 por matyvico »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #80 en: 09 de Febrero de 2013, 01:33:17 »
 :shock:

jeje lo intentaré explicar brevemente...  :mrgreen:

Código: [Seleccionar]
#define SIZE_AR(type, object) (sizeof(type) * sizeof(object))
Cada vez que el compilador encuentre la palabra SIZE_AR seguida de dos parámetros, sustituirá todo por (sizeof(type) * sizeof(object))

sizeof(type) equivaldrá al tamaño en bytes del tipo de dato que le pases. Si le pasas char, valdrá 1.

sizeof(object) equivaldrá al tamaño de elementos que el objeto tenga, si es un arreglo. Si es una variable normal, devolverá su tamaño en bytes.

Código: [Seleccionar]
(SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST)
Esto equivale a:

Código: [Seleccionar]
(sizeof(char) * sizeof(strings)) / 15 / 7
que a su vez equivale a:

Código: [Seleccionar]
(1 * 210) / 15 / 7
Código: [Seleccionar]
memcpy(opc_menu, opc_onda, SIZE_AR(char, opc_onda));
Esa te queda de tarea googlearla.

Y tu última pregunta se explica con lo anterior.

El #define es una instrucción al preprocesador (lo que corre antes del compilador) para que reemplace texto que tú pones por el que el define ordena.

Si yo hago

#define GATO "miau"

entonces

printf(GATO);

se suustituirá por

printf("miau");

al empezar la compilación.  :mrgreen:

Desconectado matyvico

  • PIC10
  • *
  • Mensajes: 20
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #81 en: 09 de Febrero de 2013, 12:40:43 »
:shock:

jeje lo intentaré explicar brevemente...  :mrgreen:

Código: [Seleccionar]
#define SIZE_AR(type, object) (sizeof(type) * sizeof(object))
Cada vez que el compilador encuentre la palabra SIZE_AR seguida de dos parámetros, sustituirá todo por (sizeof(type) * sizeof(object))

sizeof(type) equivaldrá al tamaño en bytes del tipo de dato que le pases. Si le pasas char, valdrá 1.

sizeof(object) equivaldrá al tamaño de elementos que el objeto tenga, si es un arreglo. Si es una variable normal, devolverá su tamaño en bytes.

Código: [Seleccionar]
(SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST)
Esto equivale a:

Código: [Seleccionar]
(sizeof(char) * sizeof(strings)) / 15 / 7
que a su vez equivale a:

Código: [Seleccionar]
(1 * 210) / 15 / 7
Código: [Seleccionar]
memcpy(opc_menu, opc_onda, SIZE_AR(char, opc_onda));
Esa te queda de tarea googlearla.

Y tu última pregunta se explica con lo anterior.

El #define es una instrucción al preprocesador (lo que corre antes del compilador) para que reemplace texto que tú pones por el que el define ordena.

Si yo hago

#define GATO "miau"

entonces

printf(GATO);

se suustituirá por

printf("miau");

al empezar la compilación.  :mrgreen:

Bueno, primero que nada gracias por tomarte el tiempo de escribir y responder!

Cuando escribí las preguntas debería haber achicado un poco mas la pregunta en si jaja, haber... todo lo que me explicaste respecto al #DEFINE lo sabía, igual que lo que hace la función memcpy(). A lo que apuntaba poniendo todas esas líneas de código es que, si las revisas, todas o la mayoría contienen por ejemplo:

Código: [Seleccionar]
(SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST)
Entiendo que al hacer el #DEFINE el compilador termine reemplazando todo por:

Código: [Seleccionar]
(1 * 210) / 15 / 7
Ahora bien, lo que no me queda en claro, (porque esto es a lo que me refería que nunca vi) es que significa el código anterior, el (1*210) lo entiendo, lo que no entiendo es eso en conjunto con el / 15 / 7. A que hace referencia esa barra? agrega parámetros? Porque no veo como pueda "entender" el for un argumento como este como límite:

Código: [Seleccionar]
for(menu = 0; menu < (SIZE_AR(char, strings) / MAX_CHARS_PER_STRING / MAX_ELEMS_PER_LIST); ++menu)
Disculpa y perdón por haberme hecho entender mal! Muchas gracias de nuevo!

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #82 en: 09 de Febrero de 2013, 20:29:49 »
El operador / funciona como división.  ;-)

Desconectado matyvico

  • PIC10
  • *
  • Mensajes: 20
Re: Tutorial - Cadenas y arreglos de chars
« Respuesta #83 en: 09 de Febrero de 2013, 20:48:05 »
El operador / funciona como división.  ;-)

 :z) no se me había ocurrido eso jajajaja ahora si que tiene sentido la instrucción

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #84 en: 18 de Agosto de 2016, 14:54:33 »
Un tutorial excelente.

No se si emigró a otro tema pero no veo la función strtok. 

Me  gustaría saber como utilizarla o alguien puede explicar con algún ejemplo como funciona. 

Gracias...   :-/
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #85 en: 18 de Agosto de 2016, 15:29:59 »
Pertenece a la libreria de C, string.h

http://www.cplusplus.com/reference/cstring/strtok/

Código: C
  1. char * strtok ( char * str, const char * delimiters );

Desconectado Tecmer123

  • PIC10
  • *
  • Mensajes: 1
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #86 en: 14 de Septiembre de 2016, 14:38:53 »
Buen dia, tengo la siguiente duda y quisiera que me ayuden, estoy trabajando en un proyecto sobre un modem satelital envio un codigo para encender el modem y el gps etc, y me devuelve un codigo, lo que estoy haciendo es enviar el codigo y almacenar lo que me envie en n vector, pero necesito solamente algunos bytes de lo que me responde, no se como darle lectura solamente a eso gracias.
 adjunto la parte el codigo


#include <18f2550.h>
#use delay(clock=4mhz)
#USE RS232(BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7, PARITY=N ,BITS=8,stop=1, ERRORS,stream=PIC)
char e[18]="AA06FD216FA8";
char d[16]="AA052576B2";
char T[18]="AA06FD00E498";
char I[14]="AA 0C 52 00 00 00 00 00 00 00 95 29";
char estado[16];
char c [13];
char f;

#define LCD_RS_PIN      PIN_B0
#define LCD_RW_PIN      PIN_A0                           
#define LCD_DATA4       PIN_A3                                   
#define LCD_DATA5       PIN_B3                                 
#define LCD_DATA6       PIN_B2                                   
#define LCD_DATA7       PIN_A2
#define LCD_ENABLE_PIN     PIN_A1



#include <lcd.c>
//a=gps_on
//d=gps_off

void main()
   
{
 
   puts(e,PIC);//ENCENDER
  // set_tris_B(0b00000000);
   lcd_init();
   delay_ms(300);
   lcd_gotoxy(1,1);
   lcd_putc("   recibiendo   ");
   signed int8 i=0;
 
 
   while(true) // pedir ubicacion
   {
   puts (d,PIC);
   
   
 if(kbhit(PIC)>>14) // verifica cuando llega un dato serial
    {
    estado=getc();
    i++;
    }
    i[3] // creo que algo asi se puede hacer
    i[4]// pero no se como declararlo
    i[5]  //.
       
       
    }
}

Desconectado Arsenic

  • PIC10
  • *
  • Mensajes: 47
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #87 en: 11 de Noviembre de 2017, 04:57:49 »
Buenas, amigos! Tengo la siguiente incertidumbre:
Yo recibo un código cualquiera en un puerto. Ese código me devuelve un número en hexadecimal y necesito asignarle una etiqueta en string. Es decir, quiero hacer el proceso inverso al que ya explicaron. Si, por ejemplo recibiera en el Rx: 0xD7, quiero que me devuelva "Botón 1" en el LCD. Y así con cada uno de los 25 botones. ¿Alguna sugerencia?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #88 en: 11 de Noviembre de 2017, 06:50:26 »
Defini cual es el "rango" de posibles valores en la entrada del puerto que queres que tengan un mensaje.

Ejemplo, si 0xD7 es "Boton 1", podriamos suponer que 0xD8 es "Boton 2",  y asi consecutivamente hasta "Boton 9" que seria 0xDF.

Si esto es asi, lo unico que me queda realizar es:

- Verificar si es mayor o igual a 0xD7 y menor o igual a 0xDF
- Si lo es Restarle 0xD7, esto nos va a dejar de 0x00 a 0x08 los valores
- Con ese numero llamar a un array que tiene los valores de "Boton 1", "Boton 2", etc. siendo los indices el 0 el del boton 1.

El problema se presenta cuando los valores no son continuos o respetan cierta diferencia de valores.
« Última modificación: 11 de Noviembre de 2017, 07:06:54 por KILLERJC »

Desconectado micronet3

  • PIC18
  • ****
  • Mensajes: 288
Re:Tutorial - Cadenas y arreglos de chars
« Respuesta #89 en: 13 de Noviembre de 2017, 13:43:05 »
Saludos, yo tengo un pic que recibe datos por el puerto serie, estos los recibo uno a uno y los voy guardando en un buffer hasta que llega un enter
el fin  de trama lo detecto cuando llega un 13, pero me gustaria hacer un fin de trama mas fiable, debido a que un dato puede tener ese valor y el pic lo interpretaria como un 13(enter)

una solucion que le dado es detectar un 13(retorno de carro)+10(nueva linea) consecutivamente, pero me pregunto si esto sera suficiente, espero su concejos!!

otra pregunta, seria recomendable un buffer de este tamaño?: char buffer[612]; es que quiero recibir esa cantidad de datos






« Última modificación: 13 de Noviembre de 2017, 13:58:05 por micronet3 »