TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: migsantiago en 28 de Abril de 2009, 19:22:50

Título: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 28 de Abril de 2009, 19:22:50
Gracias a que existen compiladores de C para pics es posible que los micros puedan entregar resultados en forma de texto y no en bits. Los compiladores de C normal (nada de c++, ni c#, ni java) no manejan variables tipo string pero manejan algo similar: arreglos de chars.

La variable char mide 8 bits y puede expresar datos de 0 a 255 (256 valores). Comúnmente se vincula un char a una letra o caracter del código ascii dependiendo del valor binario que éste tenga. Por ejemplo, la letra 'a' vale 0x61 en código ascii o el espacio ' ' vale 0x20.

La tabla ascii es muy popular, acá están sus valores: http://www.asciitable.com/

Un arreglo es una sucesión de variables en memoria ram. Un arreglo de chars es una sucesión de variables de 8 bits.

Si se declara lo siguiente:

char arreglo[5];

se tendrá un arreglo de 5 elementos de tipo char. El contenido de cada char es aleatorio al arrancar el pic y usando el compilador de CCS para el ejemplo anterior. Se deberá inicializar el valor de cada elemento según el uso que se le vaya a dar.

Para convertir el arreglo de chars anterior en una cadena formal, el arreglo deberá contar con lo siguiente:

- Debe tener de 0 a 4 elementos (caracteres ascii) en las primeras 4 posiciones
- El último elemento deberá ser un NULL char que equivale a 0x00

El elemento NULL marca el fin de los caracteres útiles de la cadena. Armemos una cadena sencilla con las características que se mencionaron:

arreglo[0]='c';
arreglo[1]='a';
arreglo[2]='s';
arreglo[3]='a';
arreglo[4]=0x00;

La cadena claramente contiene 'casa'. El quinto elemento dice: 'aquí terminó el texto'.

Al usar la declaración char arreglo[5]; en realidad se está declarando un apuntador a una secuencia de chars. El apuntador se llamará arreglo y será capaz de conocer la dirección ram de un char.

Por ejemplo, si yo quisiera saber cuál es la tercera letra de mi cadena puedo hacerlo de muchas formas...

Código: [Seleccionar]
//Usando un índice con arreglo (la más fácil)
if(arreglo[2]=='s')
   //Es una s

//Usando otro apuntador de chars
char *apuntador;
apuntador = arreglo+2; //copia la dirección ram del tercer elemento de la cadena (letra s)
if(*apuntador == 's')
   //Es una s

//Usando otro apuntador de chars
char *apuntador;
apuntador = &arreglo[2]; //copia la dirección ram del tercer elemento de la cadena (letra s)
if(*apuntador == 's')
   //Es una s

El siguiente ejemplo muestra una cadena que contiene el texto útil 'Calcula'.

Código: [Seleccionar]
char cadena[30]; //Una cadena que podrá almacenar hasta 29 caracteres
cadena[0]='C';
cadena[1]='a';
cadena[2]='l';
cadena[3]='c';
cadena[4]='u';
cadena[5]='l';
cadena[6]='a';
cadena[7]=0x00;
cadena[8]='d';
cadena[9]='o';
cadena[10]='r';
cadena[11]='a';

Al insertar el null char en la octava posición sabremos que ahí terminó la cadena a pesar de que hay más letras después.

Pude haberme ahorrado el esfuerzo y declarado lo anterior más rápido:

char cadena[]="Calcula";

Al escribir lo anterior el compilador cuenta cuántos chars lleva la cadena y agrega el NULL char, obteniendo 8 elementos para el arreglo cadena. Este arreglo es de tamaño fijo a pesar de que no le declaramos uno. El uso de tal instrucción solo es válido al principio del programa. Si se desea construir una cadena a mitad de un programa es mejor usar sprintf.

Para declarar cadenas hay 2 formas básicas: cadenas de tamaño constante y cadenas dinámicas. Ya se vio la declaración de las de tamaño constante, ahora se verá la dinámica:

char *cadena;

Al no tener un tamaño la cadena puede invadir memoria ram dedicada a otros propósitos y eso se debe evitar a toda costa. Para ubicar memoria ram en CCS para cadenas dinámicas (también para arreglos de cualquier otra variable dinámica) se usa malloc(). No profundizaré en este tema porque se usa poco en microcontroladores. Ejemplo:

Código: [Seleccionar]
#USE DYNAMIC_MEMORY
...

char *cadena;

...

//Búscame ram para almacenar 30 chars consecutivos
cadena=(char *)malloc(30);

...

//Ya no voy a usar la cadena, deséchala
free(cadena);

De esa forma la cadena ocupará espacio seguro y no invadirá el espacio de otros registros.

En C se usa la función sprintf para convertir variables (enteros, chars, arreglos de chars, flotantes, etc.) en texto legible para un usuario. Lo que hace la función es construir arreglos de chars y terminarlos con un NULL char.

Ejemplo 1 - Cómo almacenar 5 cadenas en una sola cadena
Código: [Seleccionar]
char cadena[50]; //cada cadena tendrá 9 chars + 1 NULL = 10 chars

//primera palabra
sprintf(cadena,"perro");
//segunda
sprintf(cadena+10,"gato");
//tercera
sprintf(cadena+20,"ratón");
//cuarta
sprintf(cadena+30,"queso");
//quinta
sprintf(cadena+40,"leche");

Pero, ¿por qué caben 5 cadenas en una sola cadena? Sprintf se encargó de insertar las letras de la palabra más un null char al final de cada una de ellas. Al usar printf para imprimirlas, buscará el null char y ahí se detendrá sin importar qué más hay después.

Ejemplo 2 - Imprimiendo las multicadenas (sigue del ejemplo 1)
Código: [Seleccionar]
//Define el tamaño de cadena en la multicadena
#define tamano 10
...

//primera
printf("%s \n", &cadena[0*tamano]);
//segunda
printf("%s \n", &cadena[1*tamano]);
//tercera
printf("%s \n", &cadena[2*tamano]);
//cuarta
printf("%s \n", &cadena[3*tamano]);
//quinta
printf("%s \n", &cadena[4*tamano]);

Lo que saldría en pantalla sería

perro
gato
ratón
queso
leche

Y un último ejemplo más difícil en el que determino la extensión del nombre de un archivo para ver si es un archivo JPEG válido (.jpg o .JPG).

Ejemplo 3 - Detectando la extensión de un archivo
Código: [Seleccionar]
    //verifica que el archivo sea un jpg válido
    //.jpg, .JPG
    char temporal[6];
    bool jpg_valido=0;

    j=0;
    for(i=(strlen(filename)-4);i<strlen(filename);i++)
        temporal[j++]=filename[i];
    temporal[j]=0;
    if(strcmp(temporal,".jpg")==0) jpg_valido=1;
    if(strcmp(temporal,".JPG")==0) jpg_valido=1;
    //.jpeg, .JPEG
    j=0;
    for(i=(strlen(filename)-5);i<strlen(filename);i++)
        temporal[j++]=filename[i];
    temporal[j]=0;
    if(strcmp(temporal,".jpeg")==0) jpg_valido=1;
    if(strcmp(temporal,".JPEG")==0) jpg_valido=1;

Primero se posiciona en el cuarto char de atrás hacia adelante de la cadena filename gracias a la función strlen() que indica cuántos chars útiles hay en la cadena. Después copia los 4 últimos chars en otra cadena llamada temporal. Por último determina con la función strcmp si la cadena temporal es idéntica a la cadena ".JPG" o ".jpg". De ser el caso, el archivo es un JPEG.

Repite el caso para .jpeg y .JPEG.

Si pudiste entender el ejemplo 3 entonces ya te sirvió este mini tutorial de cadenas.  :D

Si lo creen necesario puedo seguir explicando funciones de concatenación de strings, comparación, conteo, etc.

Actualización.

Gera continuará explicando los demás funciones de string.h aquí:

http://www.todopic.com.ar/foros/index.php?topic=25785.msg210828#msg210828
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 28 de Abril de 2009, 21:07:36
Excelente migsantiago!!! :-/ yo pensaba hacer algo al estilo pero me ganaste de mano jaja. Si me permitis, le voy a agregar una pequeña guia para usar la libreria string.h
En breve me pongo a escribir algo. Saludos!!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: BrunoF en 28 de Abril de 2009, 22:07:32
Excelenteee!!!

Agregaría una cosita: que una vez declarado un array:

char arreglo[5];

Es ilegal intentar cargarle todos los caracteres juntos:

arreglo="casa";

Por eso recurres a hacer:

arreglo[0]='c';
arreglo[1]='a';
arreglo[2]='s';
arreglo[3]='a';
arreglo[4]=0x00;
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 29 de Abril de 2009, 00:33:16
Bueno, vamos a ver si puedo contribuir con este hilo tratando de explicar las funciones mas importantes de la biblioteca string.h q nos facilitan la vida a la hora de trabajar con strings (o bloques de memoria).
Vamos a ver cada funcion, lo que hace, su sintaxis y su uso :wink:

Funciones:
strcpy   copia una cadena
strcat   concatena cadenas
strcmp   compara dos cadenas
strchr   localiza la primera ocurrencia de un caracter en una cadena
strrchr   localiza la ultima ocurrencia de un caracter en una cadena
strstr   localiza una sub cadena
strtok   divide una cadena en elementos (tokens)
memset   llena un espacio de memoria (puede llenar una cadena con un caracter dado)
strlen   obtiene la longitud de una cadena en caracteres (bytes)

Macros
NULL   puntero nulo

Tipos
size_t   entero sin signo q se utiliza para indicar el tamaño de una cadena

Bueno, empecemos a ver funcion por funcion qué hace cada una, y como se usa.


Funcion: strcpy

Sintaxis: char *strcpy(char *destino, const char *origen);
Vemos que la función recibe dos punteros, uno que apunta a la cadena de origen, y otro al destino. El valor retornado por strcpy es un puntero al destino.

Descripción:
Esta función copia caracter a caracter el contenido de una cadena a otra, incluyendo el caracter nulo. Muchas veces he visto que alguien quiere igualar cadenas haciendo algo como esto
string1=string2; MAL
Esto es una igualación de punteros. Osea, estamos haciendo que el puntero "string2" apunte al mismo lugar que "string1". Y si éstos fueron declarados como arreglos, es imposible hacer esto, ya que son puntero estáticos y cada uno apunta al lugar de memoria que le fue asignado.
Entonces, cómo hacemos si queremos que el arreglo "string2" tenga el mismo contenido que "string1"? Simplemente con strcpy ;)

Ejemplo:
Código: C
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. void main()
  5. {
  6.         char string1[]="ejemplo de string"; //son 17 caracteres mas el nulo
  7.         char string2[20];               //tiene q ser de tama&#241;o mayor o igual a string1
  8.         strcpy(string2,string1);
  9.         printf("string2: %s\n",string2);
  10. }

Comentarios:
Es importante que el destino tenga más posiciones de memoria reservadas que el origen, ya que podemos salirnos del espacio de memoria del destino y pisar otra variable. También conviene limpiar la cadena de destino antes de hacer la copia (seria análogo a inicializar una variable), esto se hace con la función memset() que vamos a ver más adelante.


Funcion: strcat

Sintaxis: char *strcat(char *destino, const char *origen);
Esta función recibe dos punteros. El primero apunta a la cadena original a la cual le queremos añadir otra, y el segundo apunta a la cadena que queremos añadir. Retorna el puntero

Descripción:
La función strcat, concatena dos cadenas. O sea, añade una cadena al final de otra, suprimiendo el caracter nulo de la última. Hay que tener cuidado de no excedernos de los limites de memoria de la cadena de destino.

Ejemplo:
Código: C
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. void main()
  5. {
  6.         char string[20]="hola ";
  7.         strcat(string,"amigos!");
  8.         printf("string: %s\n",string);
  9. }

Comentarios:
Como ya dijimos, la cadena afectada tiene que tener suficiente memoria reservada como para contener el total de los caracteres. De lo contrario podría producirse un error.
Además vemos que a la función le podemos pasar como parámetro una cadena directamente entre comillas. Esto se puede hacer con todas las funciones que reciban como parámetro un puntero a una cadena. Obviamente, estas cadenas se encuentran en la memoria de programa y no pueden ser modificadas ni utilizadas como variables.

Funcion: strcmp

Sintaxis: int strcmp(char *s1, char *s2);
Esta función recibe dos cadenas como parámetros y devuelve 0 si son iguales, un negativo si s1<s2 y un positivo si s1>s2.

Descripción:
Bueno, en la sintaxis ya expliqué bastante. La función básicamente sirve para saber si una cadena es igual a otra. Devolviendo 0 en este caso, y distinto de 0 si son distintas. Otro error común, es usar el operador == para saber si las cadenas son iguales:
if(string1==string2) MAL

Ejemplo:
Código: C
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. void main()
  5. {
  6.         char s1[]="hola mundo!"; //cuanta originalidad jaja
  7.         if( strcmp(s1,"chau mundo!") == 0);
  8.               printf("las cadenas son iguales");
  9.         else
  10.               printf("las cadenas son distintas");
  11. }

Comentarios:
Este ejemplo siempre va a dar negativo, salvo que pongamos como segundo parámetro de la función "hola mundo!". La única precaución que hay que tener al llamar a esta función, es que las cadenas tengan un terminador (NULL), si no puede haber un overflow.

---------------------------------------EN CONSTRUCCIÓN----------------------------------------
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 29 de Abril de 2009, 11:08:39
Excelenteee!!!

Agregaría una cosita: que una vez declarado un array:

char arreglo[5];

Es ilegal intentar cargarle todos los caracteres juntos:

arreglo="casa";

Por eso recurres a hacer:

arreglo[0]='c';
arreglo[1]='a';
arreglo[2]='s';
arreglo[3]='a';
arreglo[4]=0x00;


Sí Bruno, ya está mencionado en el tutorial. En esos casos habrá que recurrir al armado manual de la cadena o al uso de sprintf.  :mrgreen: En compiladores como c++, c# o java el uso de arreglo="casa"; a medio programa sí es posible, pero en c a secas es ilegal.

Gera, puedes seguir sin problemas con el uso de strings.h.  :-/

Ah y por cierto, hay un error en el ejemplo 3. El que lo encuentre se llevará una estrellita.  :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 29 de Abril de 2009, 12:49:39
Bueno, ya largué con una de las funciones, de a poco voy a ir explicando todas. Cualquier cosa q se me escape o me haya equivocado me lo hacen saber por favor.
Santi, creo q tu error esta acá:
for(i=(strlen(filename)-4);i<strlen(filename);i++)
deberia ser -3 no?
saludos!!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 29 de Abril de 2009, 13:11:47
Bueno, ya largué con una de las funciones, de a poco voy a ir explicando todas. Cualquier cosa q se me escape o me haya equivocado me lo hacen saber por favor.
Santi, creo q tu error esta acá:
for(i=(strlen(filename)-4);i<strlen(filename);i++)
deberia ser -3 no?
saludos!!!

Nop. Esa función está bien. Debe ser -4 porque cuento con todo y el punto: ".JPG". Y es -5 para el caso de ".JPEG".

Por ahí anda el error todavía, dale otra checada.  :D

Me costó trabajo pero ya conseguí la estrellita (http://www.todopic.com.ar/foros/Themes/babylon/images/star.gif)  ¿Quién la quiere?
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 29 de Abril de 2009, 13:56:54
Tenes razón, se me escapó el hecho de q filename[0] es el primer caracter jeje. Creo q el error es la definición de "temporal"
char temporal[4];
Deberia ser de tamaño 5, ya que ".jpg" son 5 caracteres incluyendo el nulo.
A todo esto, no es mas corto hacer un strstr(filename,".jpg");? jejeje. Lo voy a poner como ejemplo cuando haga en analisis de esa funcion ;)
saludos!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: AKENAFAB en 29 de Abril de 2009, 14:11:16

A la!

 :-/

Que buen temazo , hasta ahora vengo entendiendo  xD

No se donde esra el error xD asi que diremos entendo 2 de 4 xD

Asi que me quedo perfecto para un programa que desarrollo y se porque va el null y ese rollo del sprintf , que siempre he sido piedra con el C , sino es por los amigos.


Un Saludo y gracias!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 29 de Abril de 2009, 16:54:48
Tenes razón, se me escapó el hecho de q filename[0] es el primer caracter jeje. Creo q el error es la definición de "temporal"
char temporal[4];
Deberia ser de tamaño 5, ya que ".jpg" son 5 caracteres incluyendo el nulo.
A todo esto, no es mas corto hacer un strstr(filename,".jpg");? jejeje. Lo voy a poner como ejemplo cuando haga en analisis de esa funcion ;)
saludos!

¿Qué pasó Gera? Noooo.

El error está ahí pero temporal no debe medir 5. Debe ser:

char temporal[6];

Para que quepa ".JPEG" + NULL.

Bueno, me guardo la estrellita  :D

Sobre las mejorías que se harían al algoritmo, tienes razón se pueden hacer, pero hace 1 año que lo escribí apenas entendía esto de las cadenas y no me aventuraba a usar las funciones de string.h.  :P
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 29 de Abril de 2009, 20:09:22
De una, es muy buen ejercicio hacer este tipo de funciones. Cuando yo vi arreglos en C, mi profe nos hizo reescribir toda la libreria string.h como ejercicio jeje.
en fin, mas tarde sigo con la explicacion. Saludos!!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Cryn en 29 de Abril de 2009, 23:47:57
geniales explicaciones vi una libreria string.h pero para usarlo en la universidad cuando programaba en c++

y siempre tuve algunas dudas con las cadenas en CCS, gracias por el Tutorial

 :-/ :-/
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: El_Guitre en 30 de Abril de 2009, 00:45:11
Migsantiago, respecto al error del ejemplo 3, al finalizar el bucle for cuando pones temporal[j]=0; para agregarle el NULL al final de la cadena, no debería ser temporal[j++]=0; para no sobrescribir el ultimo caracter que cargaste en el for? O estoy muy errado? Saludos.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 30 de Abril de 2009, 01:17:26
Guitre, esa parte del programa esta bien. El j++ significa q j se tiene q incrementar al terminar de ejecutar esa linea. Por lo tanto si el ultimo caracter a copiar era el quinto, este se iba a copiar, y ademas j iba a quedar en 6. Por lo tanto el caracter nulo iba a quedar en la sexta posicion sin pisar nada. Caso contrario si ponemos ++j. Esto primero incrementa j, y luego ejecuta la linea.
Saludos!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 30 de Abril de 2009, 12:44:46
Ampliando la explicación de Gera, explico la enorme diferencia entre ++i y i++.

A muchos nos dicen erróneamente en la escuela que ambos son iguales pero no es cierto.

++i
Al ser invocado se incrementa el contenido de i y luego se usa su valor. Ejemplo:

Código: [Seleccionar]
int i=0;

printf("i vale %u",i);
printf("i vale %u",++i);
printf("i vale %u",i);

La salida del código es

Código: [Seleccionar]
i vale 0
i vale 1
i vale 1

i++
Al ser invocado primero se usa el valor actual de i y luego se incrementa. Ejemplo:

Código: [Seleccionar]
int i=0;

printf("i vale %u",i);
printf("i vale %u",i++);
printf("i vale %u",i);

La salida es:

Código: [Seleccionar]
i vale 0
i vale 0
i vale 1

El caso aplica de la misma forma con --i y i--.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: El_Guitre en 30 de Abril de 2009, 12:48:56
Chanfle, estaba muyyy errado. Gracias a los dos por la aclaracion.
Hay un pequeño error en el ejemplo de i++, quedo puesto printf("i vale %u",++i); en el ejemplo
Saludos.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 30 de Abril de 2009, 12:52:31
Corregido, gracias. Te ganaste una estrellita Güitre: (http://www.todopic.com.ar/foros/Themes/babylon/images/star.gif).

Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: El_Guitre en 30 de Abril de 2009, 13:33:53
Corregido, gracias. Te ganaste una estrellita Güitre: (http://www.todopic.com.ar/foros/Themes/babylon/images/star.gif).

Gracias  :-/ :-/ la voy a guardar en mi firma por un tiempo, jaja
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 30 de Abril de 2009, 14:50:50
Jajaja, qué bueno que te gustó el regalo. Gera no lo quiso, le hizo 'fuchi'  :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 30 de Abril de 2009, 16:17:11
Jajaja, qué bueno que te gustó el regalo. Gera no lo quiso, le hizo 'fuchi'  :D
Woow woow woow... como q gera no lo quiso? no sabia q habia q ponerlo en la firma a modo de aceptacion jaja. Ya llevo bastante en el foro, pero no conocia esta costumbre jeje.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 30 de Abril de 2009, 16:34:01
jajaja

No, tú puedes hacer lo que quieras con la estrellita, pero primero te la tienes que ganar.  :D

Vamos Gera, continúa con el tutorial que la gente quiere aprender  :mrgreen:
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 30 de Abril de 2009, 16:58:29
Buu, por dormilon me la gano el guitre de guitre jaja. Voy a resumir una función mas y a seguir estudiando :( jeje
saludos!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: PalitroqueZ en 30 de Abril de 2009, 17:06:15
`tan muy buenas las explicaciones señores Santiago y Gera.  :-) :-)

Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: El_Guitre en 30 de Abril de 2009, 19:11:46
Buu, por dormilon me la gano el guitre de guitre jaja. Voy a resumir una función mas y a seguir estudiando :( jeje
saludos!!

jaja, lo de poner la estrella en la firma no es una costumbre ni mucho menos. Se me ocurrió ponerla ahí por que es el único lugar donde podría verse y mostrar mi agradecimiento  :mrgreen:
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 28 de Mayo de 2009, 22:36:02
Hoy leí una noticia sobre el nuevo CCS 4.100, se agregaron los nuevos pic de medio rango (PIC16 mejorados) y además algo que yo no esperaba en un compilador de C...

http://www.ccsinfo.com/newsdesk_info.php?newsPath=ALL&newsdesk_id=111

Citar
CCS C Compiler Release of Principal Version 4.100
Wednesday 27 May, 2009

Version 4.100 Supports Microchip Technology's Enhanced Mid-Range Family of PIC16 MCU!

CCS announces the release of version 4.100 for all CCS C Compilers in June 2009. This release includes many new and exciting features, functionality and support.

CCS has improved string-handling functions to be optimized built-in functions that will accept any combination of constant and variable arguments. The new compiler also includes an optimized printf, including string compression for 7-bit ASCII strings on 14-bit opcode parts. Many printf strings will take half of the ROM space on most PIC® microcontrollers from Microchip Technology.

The newly added syntax extensions will allow the use of some standard operators, such as +, = and ==, directly on strings. Powerful syntax extensions also permit the use of strings in a switch statement, providing an easy to use and efficient string comparison.

Additionally, version 4.100 includes support for the enhanced Mid-range family of PIC® microcontrollers, including large arrays and built-in functions such as a context switch. The compiler includes a library for #USE TOUCH_PAD for capacitive touch-sensing. PIC® microcontrollers with the onboard mTouch™ module, such as the PIC16F727, will utilize internal features when available.

“CCS has always offered unique value to Microchip’s customers,” said Derek Carlson, vice president of Microchip’s Development Tools group. “We are pleased that the CCS C Compiler now supports our enhanced Mid-range PIC® microcontrollers The support is timely and welcome.”

Version 4.100 will be available to any customer on active maintenance.

Sí, tal como lo leen, CCS aceptará modificar strings con el operando +, = y ==. Ya no hará falta usar las engorrosas sprintf o strcat para concatenar arreglos de chars.

Busqué en el manual de CCS en línea y todavía no comentan la forma de usarlos, seguramente cuando se libere la 4.100 liberarán el nuevo manual.

Esto ayudaría en mucho el manejo y comparación de strings.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: BrunoF en 28 de Mayo de 2009, 22:44:05
La verdad que es un notición. Especialmente por la facilidad que traerá y por la reducción de memoria ROM que ahorrarán las nuevas mejoras al compilador. Justo yo que ayer me quejaba de cómo me devoran ROM los strings...
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 28 de Mayo de 2009, 22:51:20
Sí, no cabe duda que la gente de CCS le da un valor agregado extra a los pics, mucho más valor que otros compiladores. No falta mucho para que agreguen la recursividad que tanto hizo enojar a Nocturno. :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: MLO__ en 28 de Mayo de 2009, 23:38:46
Hay que esperar a que este disponible  :mrgreen:
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 29 de Mayo de 2009, 00:11:11
Hmmm... a mi no me gusta para nada. Sera muy bonito, pero ya no es C. Pero bueh, yo tengo esas roscas de informatico jaja. Supongo q le va a facilitar la vida a muchos.
Por cierto, me habia re olvidado q yo estaba explicando las funciones aca jaja. Mil perdones, es q en la epoca de mesas me vuelo. Pronto seguire con ese trabajito.
saludos!!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: jeremylf en 21 de Julio de 2009, 14:58:41
A mi no me va las funciones de comparacion, cuando pongo:

if (strcmp(Buffer, "JEJE") == 0)
{
...
}

Me vota error: Attempt to create a pointer to a constant.

Sera por el compilador? Estoy usando el 4.023
Que salga de una vez esa similitud al c++ porque estas funciones del stdlib me estan inchando las bolas  :D


Salu2.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Cryn en 21 de Julio de 2009, 16:04:37
es porque strcmp usa punteros, y como sabes no se puede usar un puntero a una constante, en este caso "JEJE" sería constante, lo que se tendría que hacer es:

char temp[5]="\0";

strcpy(temp,"JEJE");
if(strcmp(Buffer,temp)==0){
...
...
}

saludos
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: jeremylf en 21 de Julio de 2009, 18:48:45
Claro, pero lo digo porque gera lo hizo asi. Mira:

Funcion: strcmp

Sintaxis: int strcmp(char *s1, char *s2);
Esta función recibe dos cadenas como parámetros y devuelve 0 si son iguales, un negativo si s1<s2 y un positivo si s1>s2.

Descripción:
Bueno, en la sintaxis ya expliqué bastante. La función básicamente sirve para saber si una cadena es igual a otra. Devolviendo 0 en este caso, y distinto de 0 si son distintas. Otro error común, es usar el operador == para saber si las cadenas son iguales:
if(string1==string2) MAL

Ejemplo:
Código: C
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. void main()
  5. {
  6.         char s1="hola mundo!"; //cuanta originalidad jaja
  7.         if( strcmp(s1,"chau mundo!") == 0);
  8.               printf("las cadenas son iguales");
  9.         else
  10.               printf("las cadenas son distintas");
  11. }

Comentarios:
Este ejemplo siempre va a dar negativo, salvo que pongamos como segundo parámetro de la función "hola mundo!". La única precaución que hay que tener al llamar a esta función, es que las cadenas tengan un terminador (NULL), si no puede haber un overflow.

---------------------------------------EN CONSTRUCCIÓN----------------------------------------
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Cryn en 21 de Julio de 2009, 19:16:14
pequeño error seguramente que no se lo estaba viendo, porque es incorrecto usar constantes en strcmp

saludos
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 21 de Julio de 2009, 20:25:07
Hmm, en ese ejemplo me falto declarar s1 asi:
Código: C
  1. char s1[]="hola mundo!";

Y en cualquier compilador de C estandar se le puede pasar una constante como parametro a strcmp. Ya que la funcion usa punteros propios para determinar si las cadenas son iguales.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: MLO__ en 21 de Julio de 2009, 22:39:33
No olvidemos que CCS no es C estandar.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 21 de Julio de 2009, 23:42:38
No olvidemos que CCS no es C estandar.

No, y la verdad q a veces me molesta. Pero bueh, antes q andar programando en asm... jajaja
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: jeremylf en 22 de Julio de 2009, 01:29:15
Entonces, en teoria, deberia poderse pero como CCS es otra webada (no es C estandar) no se puede... Vaya Mie"#$%  :lol:

Con punteros previos sera entonces.
Gracias por la aclaracion.

Salu2.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 30 de Julio de 2009, 01:26:24
hola, que pasa si formamos un arrays de cadenas

char cadena[5][10]={"hola","como","estas","bien","gracias"};

eso si se puede, donde el primer indice indica el numero de cadenas que se pueden almacenar, y el segundo indice el tamaño de cada cadena.
 
habria alguna forma de asignarle a cadena, las cadenas dentro del bucle del programa principal, ya que eso no he podido, o en todo caso sprintf parece una solucion.
lo que se me ocurre hacer es lo siguiente

char cadena[5][10];

void main{
cadena[0]="hola";
cadena[1]="como";
cadena[1]="estas";
cadena[1]="bien";
cadena[1]="gracias";


while(true)
{
}
}


se que lo anterior esta mal, como se haria de otra manera, hay forma


Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 30 de Julio de 2009, 01:30:04
aa disculpen se me paso, es asi

char cadena[5][10];

void main{
cadena[0]="hola";
cadena[1]="como";
cadena[2]="estas";
cadena[3]="bien";
cadena[4]="gracias";


while(true)
{
}
}

Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 30 de Julio de 2009, 01:44:41
sprintf puede funcionar, pero hay una funcion q hace lo q queres: strcpy. Unos posts arriba explico como se usa.
Saludos!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 30 de Julio de 2009, 08:18:16
gracias amigo gera, efectivamente funciona ya los probe de las dos formas y funciona, en almacen valga la redundancia almaceno datos enviado desde la pc y funciona correctamente
char almacen[5][5]



  strcpy(almacen[j],dato);
  USART_activa_tx_nodo();
  fprintf(nodo,"%s\r","dato agregado");
  USART_activa_rx_nodo();
 j++;
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 30 de Julio de 2009, 08:36:06
gracias amigo gera, efectivamente funciona ya los probe de las dos formas y funciona, en almacen valga la redundancia almaceno datos enviado desde la pc y funciona correctamente
char almacen[5][5]



  strcpy(almacen[j],dato);
  USART_activa_tx_nodo();
  fprintf(nodo,"%s\r","dato agregado");
  USART_activa_rx_nodo();
 j++;


upss creo que meti la pata, asi no funciona, primero lo hice con sprintf, asi si funciono, despues hize un guardar como, y cambie el codigo para probarlo con strcpy, pero resulta que cuando compilaba supuestamente , compilaba el codigo que habia hecho con sprintf,
me sale error, no compila..
upssssss disculpa
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 30 de Julio de 2009, 12:11:36
Cual es el error? Asegurate q lo q le pasas a strcpy son dos punteros, y q almacen tenga espacio suficiente como para contener a dato.
Saludos!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 30 de Julio de 2009, 19:38:01
ok gera, voy a revisar el codigo y despues les digo que paso, muchas gracias
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 31 de Julio de 2009, 23:47:37
gera, ahi esta el ejemplo, parece que el ccs no soporta crear matrices de cadenas, ten en cuenta que yo en creado una matriz,  lo unico que imprime es "HI"
 
Citar
#include <16F628A.h>

#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_B2,rcv=PIN_B1,stream=esclavo)

char mensaje[10][5];
char men1[5]="hi\0";
char men2[5]="ho\0";
char men3[5]="la\0";
char men4[5]="co\0";
char men5[5]="mo\0";
char men6[5]="es\0";
char men7[5]="tas\0";


//rutina de interrupcion
#int_rda
void interrupt_service_rutine_rda(void)
 {

 }

void main(void) {

        int i;
        setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
        setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
        setup_timer_2(T2_DISABLED,0,1);
        setup_comparator(NC_NC_NC_NC);
        setup_vref(FALSE);
        port_b_pullups(False);
        set_tris_b(0b00000010);
     
        delay_ms(100);
        enable_interrupts(global);
        enable_interrupts(int_rda);
       
       fprintf(esclavo,"%s","hi");
       strcpy( mensaje,men1);
       i++;
       strcpy( mensaje,men2);
       i++;
       strcpy( mensaje,men3);
       i++;
       strcpy( mensaje,men4);
       i++;
       strcpy( mensaje,men5);
       i++;
       strcpy( mensaje,men6);
       i++;
       strcpy( mensaje,men7);
       for(i=0;i<7;i++)
       fprintf(esclavo,"%s",mensaje);
   
      }
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 31 de Julio de 2009, 23:51:16
ahi no ha salido en indice no se porque, pero es asi

 strcpy( mensaje,men1);
       i++;
       strcpy( mensaje,men2);
       i++;
       strcpy( mensaje,men3);
       i++;
       strcpy( mensaje,men4);
       i++;
       strcpy( mensaje,men5);
       i++;
       strcpy( mensaje,men6);
       i++;
       strcpy( mensaje,men7);
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 31 de Julio de 2009, 23:52:26
tampoco no sale
bueno es algo asi

strcpy( mensaje[1],men2);
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Suky en 01 de Agosto de 2009, 00:10:17
Hola micronet3:
Para definir una matriz con mensajes:
Código: C
  1. char Mensajes[5][10]={{"Primero"},{"Segundo"},{"Tercer"},{"Cuarto"},{"Quinto"}};

Y para reemplazar los mensajes:
Código: C
  1. strcpy(Mensajes[1],"Reemplazo");// cambio "Segundo" por "Reemplazo"

Acuérdate que se agrega '\0' por lo que tu matriz debe tener el tamaño apropiado.

Saludos!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 01 de Agosto de 2009, 00:38:08
Si "mensaje" es un arreglo de dos dimensiones, entonces a la funcion strcpy le tendrias q pasar al menos un indice
strcpy(mensaje,men1);
Acordate q strcpy recibe como parametro un puntero, y "mensaje" asi como esta es un puntero doble.
Proba y contanos q tal.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 01 de Agosto de 2009, 06:25:10
asi si funciona.

#include <16F628A.h>

#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_B2,rcv=PIN_B1,stream=esclavo)

char mensaje[5][6];
//rutina de interrupcion
#int_rda
void interrupt_service_rutine_rda(void)
 {
 }

void main(void) {

        int i=0;
        setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
        setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
        setup_timer_2(T2_DISABLED,0,1);
        setup_comparator(NC_NC_NC_NC);
        setup_vref(FALSE);
        port_b_pullups(False);
        set_tris_b(0b00000010);
        delay_ms(100);
        enable_interrupts(global);
        enable_interrupts(int_rda);
        strcpy(mensaje,"perro");
        i++;
        strcpy(mensaje,"loro");
         i++;
        strcpy(mensaje,"gato");
         i++;
        strcpy(mensaje,"raton");
         i++;
        strcpy(mensaje,"tigre");
       for(i=0;i<5;i++)
       fprintf(esclavo,"%s\n\r",mensaje);
      }
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 01 de Agosto de 2009, 07:58:44
aja, ya parece que encontre la luz, miren esto, la clave esta en que el nombre de un vector es un puntero

#include <16F628A.h>

#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_B2,rcv=PIN_B1,stream=esclavo)

char mensaje[10];

char *apuntador;
//rutina de interrupcion
#int_rda
void interrupt_service_rutine_rda(void)
 {
 }

void main(void) {

        int i=0;
        setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
        setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
        setup_timer_2(T2_DISABLED,0,1);
        setup_comparator(NC_NC_NC_NC);
        setup_vref(FALSE);
        port_b_pullups(False);
        set_tris_b(0b00000010);
        delay_ms(100);
        enable_interrupts(global);
        enable_interrupts(int_rda);
        mensaje[0]='h';
        mensaje[1]='o';
        mensaje[2]='l';
        mensaje[3]='a';
        mensaje[4]=0x00;
        mensaje[5]='c';
        mensaje[6]='o';
        mensaje[7]='m';
        mensaje[8]='o';
        mensaje[9]=0x00;
     
        fprintf(esclavo,"%s\r",mensaje+1);
        fprintf(esclavo,"%s\r",&mensaje[5]);
        apuntador=&mensaje[0];
        fprintf(esclavo,"%s\r",apuntador);
        apuntador=&mensaje[5];
        fprintf(esclavo,"%s\r",apuntador);
      }
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 01 de Agosto de 2009, 08:27:17
creo que seria mucho pedir al ccs, pero por las dudas, el ccs permite declarar punteros dobles?
he declarado y no acepta, o hay alguna sintaxis especial?
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: MLO__ en 01 de Agosto de 2009, 11:01:36
Te refieres a un arrego de 4 dimensiones?

Creo que el CCS si deja hacer eso, pero con el micro que estas trabajando esta muy limitado en memoria.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 02 de Agosto de 2009, 10:31:14
mm no, me refiero a que si permite declarar punteros dobles, que segun lei se utiliza en una matriz

hacer asi
 int **p;
int *q;
lo he declarado pero lamentablemente no lo acepta. mmm pero como dice gera, cuando declaras una matriz
int p[2][3];  ahi hay un puntero simple y un puntero doble.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: gera en 02 de Agosto de 2009, 14:26:43
No te deja declarar punteros dobles? Q clase de compilador es?
Se me ocurre q podrias definir un tipo, y un puntero a ese tipo, seria algo asi:
typedef int* pint_t;
pint_t *p;

Proba y contame como te va.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 en 04 de Agosto de 2009, 23:00:06
que interesante, tal vez esa sea la atraccion del c, que te permite hacer o modifcar.
si lo he compilado y no genera error, voy a tratar de aplicarlo a una matriz.
disculpa por la demora, el trabajo no me da mucho tiempo.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Trev en 01 de Noviembre de 2009, 19:32:58
Hola es nuevo el tema de las cadenas para mi pero es muy interesante,lo que quiero hacer y espero ser claro es facilitarme la tarea a la hora de imprimir una nota en el lcd(ya se que no deberé abusar de muchas letras en mi frase por el tema de la memoria RAM q dispongo)

Código: [Seleccionar]
#include <16F877a.h>
#fuses HS,NOWDT,PUT,NOPROTECT,NOLVP,BROWNOUT
#use delay(clock=20000000)
#include <flex_lcd.c>
#define OFF 1
#byte portb=0x06
#use fast_io(b)

int direccion=0x80,linea_2=OFF,selector_mensajes=0,primer_error=0;
void seleccion_mensaje();
void handle_error();

main()
{
   lcd_init();
   output_low(portb);
   set_tris_b(0xf0);
   portb=0b00000000;
   port_b_pullups(true);
   enable_interrupts(global);
   enable_interrupts(int_rb);
   
   lcd_setcursor(0,0);           //Esta función controla si es visible el cursor(1º parametro)y si se activa el parpadeo.
   direccion=0x80;
   
   while(1)
   {
      seleccion_mensaje();
      delay_ms(150);
      lcd_putc("\f");
      direccion++;
      lcd_gotoxy(direccion,linea_2);
         if(direccion==0x8F)
         {
         direccion=0xC0;
         }
         if(direccion==0xCF)
         {
         direccion=0x80;
         linea_2=OFF;
         }
         switch(restart_cause())       //Funcion aviso de reinicio por fallo alimentacion.
         {
         case NORMAL_POWER_UP:
         handle_error();
         
         break;
         }     
   }
}

void seleccion_mensaje()

{
   switch(selector_mensajes)
   {
   case 0:
   lcd_putc("Anahi te amo");

   break;

   case 1:
   lcd_putc("Te queria decir");

   break;

   case 2:
   lcd_putc("que a pesar de");

   break;

   case 3:
   lcd_putc("todo lo incha");

   break;

   case 4:
   lcd_putc("que sos...");

   break;

   case 5:
   lcd_putc("= te amo..");

   break;

   case 6:
   lcd_putc("hehe");

   break;
   
   case 7:
   lcd_putc("Yo Carlos..");
   
   break;
   
   default:
   selector_mensajes=0;
   
   break;
   }
}

#int_rb
void rb_rsi()
{
if(!input(PIN_B4)){delay_ms(40);++selector_mensajes;direccion=0x80;}
output_low(portb);
}

void handle_error()
{
lcd_gotoxy(1,1);
printf(lcd_putc,"\fFallo en la alimentacion");
if(primer_error==1)
{
sleep();    //La idea es usar esto para congelar al pic y descongelarlo una vez reseteado y reparada la alimentación.
}
primer_error=1;
}
O sea que lo que quiero hacer es evitarme tener que escribir en cada case cada palabra por separado..como puedo escribir todo de una si quiero cambiar la leyenda ej. definir un array con un maximo de letras e ir partiendo la nota de forma q se imprima en pantalla 15 caracteres por vez, se puede hacer? no les pido q me hagan el trabajo pero si estan experimentados tirenme una idea de como podria hacerlo seria con strlen() y sprintf?..Gracias
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 01 de Noviembre de 2009, 19:37:19
Hola, puedes usar la memoria de programa para almacenar los caracteres.

Código: [Seleccionar]
const char mensaje1[]="Mucho amor, poca RAM."; //Guarda la cadena en la rom de programa

...

for(i=0; i<21; ++i)
   lcd_putc(mensaje1[i]);

Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Trev en 01 de Noviembre de 2009, 20:24:52
HEHE   :D si gracias capo nos vemos,aguante river carajo!!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: RALF2 en 01 de Noviembre de 2009, 21:28:56
Excelente material amigos!
Migsantiago y gera, los felicito por esa iniciativa!  :-/

Voy a leer la informnacion que colocaron a ver si puedo agregar algo de lo poco que he aprendido en estas cortas semanas qie llevo con el CCS  ;-)

Una preguntilla  :mrgreen:
Los ejemplos que van a colocar son tomando en cuenta el C o van a estar dirijidos al CCS?
Ya que hay cosas que como saben son validas en C y no en CCS.  :shock:

Saludos
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: RALF2 en 01 de Noviembre de 2009, 23:19:09
Que tal amigos!
AQui les coloco una pequeña modificacion que le hice a uno de los ejemplos de migsantiago y que podria servir como un metodo alternativo  :mrgreen:
En este ejemplo cuando se usa solo el nombre del string(cadena) este opera como un puntero al primer elemento de la cadena, luego colocandole un offset podemos mostrar el contenido de la cadena completa.  :mrgreen:

Código: [Seleccionar]
En ccs:
&cadena[i] = cadena + i    ;-)

Citar
#include <16F877a.h>
#use delay (CLOCK = 4000000)
#fuses XT,NOWDT,NOLVP

#use rs232 (baud=9600,xmit=pin_b6, rcv=pin_b7)


void main()
{
   char cadena[50]; //cada cadena tendrá 9 chars + 1 NULL = 10 chars
//primera palabra
sprintf(cadena,"perro");
//segunda
sprintf(cadena+10,"gato");
//tercera
sprintf(cadena+20,"ratón");
//cuarta
sprintf(cadena+30,"queso");
//quinta
sprintf(cadena+40,"leche");

printf("%s \n", cadena);
//segunda
printf("%s \n", cadena+10);
//tercera
printf("%s \n", cadena+20);
//cuarta
printf("%s \n", cadena+30);
//quinta
printf("%s \n", cadena+40);

while(1);


}

(http://img691.imageshack.us/img691/9872/sshot1d.png)


SAludos
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 02 de Noviembre de 2009, 00:30:30
Una preguntilla  :mrgreen:
Los ejemplos que van a colocar son tomando en cuenta el C o van a estar dirijidos al CCS?
Ya que hay cosas que como saben son validas en C y no en CCS.  :shock:

Saludos

Pues lo ideal es que los ejemplos sean para CCS porque mucha gente lo usa. Creo que el tutorial ya está completo, solo falta detallar las demás funciones de string.h pero una vez entendiendo lo básico de las cadenas esas funciones son fáciles de entender.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Hebert en 15 de Febrero de 2011, 21:03:18
ola a todos mi pregunta es la siguiente

quiero separar una cadena de la siguiente forma por ejemplo

A1=12.36//donde el numero en este caso 12.36 el cual puede variar puede ser 1000  o cualquiera


la idea es quitar el "A1=" y trabajar con el numero almacenado en otra variable, para luego pasarlo a flotante o realizar calculos con el

Muxas gracias de antemano  y disculpen la ignorancia

Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Hebert en 15 de Febrero de 2011, 21:05:18
se me olvidaba decir que trabajo con c30
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Suky en 15 de Febrero de 2011, 21:45:47
Podes usar la función strncpy de las estándar de Strings. Algo de info:

http://www.google.com.ar/search?aq=f&sourceid=chrome&ie=UTF-8&q=strncpy


Saludos!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 15 de Febrero de 2011, 22:50:29
Si la cadena origen es "A1=12.36" entonces basta con que a la cadena destino la copies con un apuntador.

Código: [Seleccionar]
char *destino;

...

destino = origen+3;
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Nocturno en 16 de Febrero de 2011, 02:45:14
Magnífico tutorial Santiago, muchas gracias
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Hebert en 16 de Febrero de 2011, 12:22:06
Muchas gracias por contestar  lo hice con el puntero y me resulto

ya me han salvado de hartas... pondre una dedicatoria en mi tesis para el foro :-/ :-/ :-/ :-/
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: pocher en 18 de Febrero de 2011, 03:11:12
Muy bueno lo de cadenas con punteros. Gracias
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 18 de Febrero de 2011, 11:08:15
Magnífico tutorial Santiago, muchas gracias

Muy bueno lo de cadenas con punteros. Gracias

Gracias por leerlo. Saludos.
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: marvicdigital en 21 de Agosto de 2011, 08:35:30
Hola a todos.
Estoy practicando con este magnífico tutorial, una campo que quiero tener muy en claro..gracias migsantiago.
Como ejemplo estoy usando el strcmp de esta forma:

Código: [Seleccionar]
for(;;){
      unsigned char activar[]="*1234";
      unsigned char codigos[6];
      unsigned char i,c;

      while(estado==0x04){    //Hasta que no sea igual no seguimos
               for(i=0;i<5;i++){
               while(c==0);         //Hasta que no se oprima alguna tecla ..está por interrupción
               codigos[i]=c;
               c=0;                    //reiniciamos c
               }
               if(strcmp(codigos,activar)==0){         //Comparamos
                  lcd_putc("\fEs Igual");
                  delay_ms(1800);
                  estado=0x05;                 //Es igual , salimos
               }else{
                  lcd_putc("\fNo es Igual");
                  estado=0x04;}

Lo curioso es que anoche me funcionó bien, hoy le hice unos cambios al código en las lines sobre que hacer si es diferente, y resulta que compilo, 0.0 errores, 0 warnigs pero no me funciona, siempre dice que es diferente. Me puse a grabar la varible activar en la eeprom, usando la variable i dentro del for, y al leerla me muestra *1234; lo mismo hice con la variable codigos dandome bien...por lo que creo que debe ser un bug del CCS o cometo un error al comparar...alguna sugerencia, por favor. Estoy usando CCS 4.120 y el 18F2550

Saludos

PD...Me respondo: Mi error está en que la variable codigos no le agrego el caracter nulo al final, para que se sepa que se ha terminado la cadena, por lo tanto algún campo de la memoria tenía el "0" anoche y hoy pues ya no estaba :) por eso me confundió....busqué como agregarle el cero y ya en este mismo hilo, vamos cosas de despistes que me quitaron 2 horas :)..bueno aca la correción:

Código: [Seleccionar]
unsigned char codigos[6]="\0";


Gracias por enseñarme, señores.
////////////////////////////////////////////////////////////

Edición 2: No entiendo que pasa, pero ya no me funciona, sigo con el mismo problema, no da como resultado la igualdad, siempre es diferente, debo tener el problema en la formación de la cadena, realmente como se hace? no logro entender, si le sumo un espacio más a la cadena para que el compilador agregue el caracter nulo, por que no me funciona?
Ayuda por favor...
Gracias de antemano

////////////////////////////////////////////////////////////

Edición 3:Jajaja, de nuevo, solo funciona si a la variable codigos le agrego el cero(en caracter nulo) luego de la rutina for.. asi:

Código: [Seleccionar]
for(i=0;i<5;i++){
               while(c==0);         //Hasta que no se oprima alguna tecla ..está por interrupción
               codigos[i]=c;
               c=0;                    //reiniciamos c
               }
codigos[5]=0;

Existe una forma más elegante de no tener que hacer esto cada vez? o la puedo declarar al inicio del programa sin problemas? Gracias.


Saludos



Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico en 26 de Enero de 2013, 19:56:29
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]);
}
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Suky en 26 de Enero de 2013, 22:23:30
Reemplazar el texto de un arreglo de char? No, con strcpy...También podes cargar directamente el string:

strcpy(opc_menu[0],"Rampa");


Saludos!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico en 07 de Febrero de 2013, 17:38:33
Reemplazar el texto de un arreglo de char? No, con strcpy...También podes cargar directamente el string:

strcpy(opc_menu[0],"Rampa");


Saludos!

Claro, quiero reemplazar el texto que contiene un arreglo char (local) por el de otro arreglo char (global), a eso lo hice funcionar, pero por lo que estuve leyendo, solo es necesario el uso del strcpy() cuando se trata de arreglos char, es decir, si por ejemplo yo quiero asignar nuevos valores a un array numerico tipo int solo haciendo:

Código: [Seleccionar]
int i;
int mi_array[200]={};

for(i=0;i<=199;i++)
{
    mi_array[i]=2*sin(i);
}

Supongo que con eso bastaría para generar un array que tenga en cada uno de sus 200 elementos un calculo particular del seno (por ejemplo).
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: MGLSOFT en 07 de Febrero de 2013, 17:46:40
Chiste.

Otra forma de hacer ese calculo (2 seno(x)) es:

Conseguir 200 mujeres y ponerlas en linea una tras otra (deben ser de talle x)  :D :D :D :D :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: Nocturno en 07 de Febrero de 2013, 18:19:22
Jaja, tu mente es perversa  :D :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago 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

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

Saludos a todos :D
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago 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 . . .
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico 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:
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico 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
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago 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:
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico 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!
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: migsantiago en 09 de Febrero de 2013, 20:29:49
El operador / funciona como división.  ;-)
Título: Re: Tutorial - Cadenas y arreglos de chars
Publicado por: matyvico 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
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: Abner_emanuel 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...   :-/
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: KILLERJC 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 );
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: Tecmer123 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]  //.
       
       
    }
}
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: Arsenic 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?
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: KILLERJC 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.
Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: micronet3 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






Título: Re:Tutorial - Cadenas y arreglos de chars
Publicado por: KILLERJC en 13 de Noviembre de 2017, 14:22:54
Se me ocurren 2 cosas, o usas los saltos de lineas (\r y/o \n ) como decis, pero sin el Enter ( 0x13 ), ya que no tendria sentido, y asi podes usarlo al enter libremente.

O la otra es tener un valor de inicio ejemplo 0xFF, seguido de la cantidad de bytes, y luego el dato, CRC si queres. De esa forma podes enviar cualquier cosa.