Autor Tema: Procesar string  (Leído 1260 veces)

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

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Procesar string
« en: 23 de Octubre de 2017, 00:47:39 »
Saludos,
Hoy tengo un problema con un dato especifico en un string,

Por ejemplo tengo este codigo que es la trama de un gps:
Código: C
  1. char str[128];                                                              
  2.    char gprmc[] = "$GPRMC,";
  3.    char tokens[] = ",";
  4.    int i;
  5.    char *p, *lat, *latDir, *lon, *lonDir, *time,*validity,*speed,*course,*date,*variation,*east,*checksum;
  6.  // !$GPRMC,045103.000,A,3014.1984,N,09749.2872,W,0.67,161.46,030913,,,A*7C
  7.       fgets(str, STREAM_GPS);
  8.       fprintf(STREAM_USB,"%s\r\n",str);
  9.       if (strstr(str, gprmc) != 0){
  10.          p = strtok(str, tokens);
  11.          i = 0;
  12.          while(p != NULL){
  13.             switch(i++){
  14.             // !$GPRMC,045103.000,A,3014.1984,N,09749.2872,W,0.67,161.46,030913,,,A*7C
  15.                case 1:  time = p;       break;      //  1   220516     Time Stamp
  16.                case 2:  validity=p;     break;      //  2   A          validity - A-ok, V-invalid
  17.                case 3:  lat = p;        break;      //  3   5133.82    current Latitude
  18.                case 4:  latDir = p;     break;      //  4   N          North/South
  19.                case 5:  lon = p;        break;      //  5   00042.24   current Longitude
  20.                case 6:  lonDir = p;     break;      //  6   W          East/West
  21.                case 7:  speed = p;      break;      //  7   173.8      Speed in knots
  22.                case 8:  course = p;     break;      //  8   231.8      True course
  23.                case 9:  date = p;       break;      //  9   130694     Date Stamp
  24.                case 10: variation = p;  break;      //  10  004.2      Variation
  25.                case 11: east = p;       break;      //  11  W          East/West
  26.                case 12: checksum = p;   break;      //  12  *70        checksum
  27.  
  28.                default: break;
  29.             }            
  30.             p = strtok(NULL, tokens);
  31.          }
Solo me interesa la velocidad, es decir la variable speed.
como hago para que cuando ese espacio este vacio no se desplace adelante o hacia atrás el valor correspondiente.
es decir, en algún momento llego  el string= a,b,c,d,  como cada espacio llego con datos pues las variables se van llenando asi:
var1=a
var2=b
var3=c
var4=d
Pero,si llega  un string=,b,,d, las variables se llenan de esta forma:
var1=b
var2=d
var3=
var4=

Mi pregunta es como hago para asignar a la variable un "0000" o el contenido que yo quiera en caso de llegar vacío.
debo garantizar siempre un "0", en caso de que no haya nada.
« Última modificación: 23 de Octubre de 2017, 01:00:49 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Procesar string
« Respuesta #1 en: 23 de Octubre de 2017, 15:03:31 »
Si esto es para un microcontrolador, porque no implementar una maquina de estado cuando este recibiendo para que separe los datos a medida que entran?

En ves de juntar todo en un buffer y luego tratar de dividirlo.

Respecto al codigo, strtok tiene que determinar el comienzo y el fin del string, para determinar el comienzo busca algun caracter que no se encuentre en la lista de token
Mientras que el final busca por el token y al encontrarlo lo reemplaza por un caracter nulo
Por eso mismo cuando tenes:

,b,,d,

El primer caracter pertenece al token, por lo tanto lo omite y llega a 'b'. ahi comienza, y finaliza en la coma que esta al lado.
Si observamos ahora nuestro texto quedarias asi:
,b\0,d, Siendo lo que le falta ,d,

Al ejecutarlo de nuevo al strtok, como comienza de nuevo con la coma entonces lo omite y comienza desde 'd'. Por eso mismo tenes 2 nomas y no 4.
La otra seria crear tu propia funcion que genere la salida que estas buscando

« Última modificación: 23 de Octubre de 2017, 15:33:07 por KILLERJC »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Procesar string
« Respuesta #2 en: 23 de Octubre de 2017, 16:18:41 »
Yo lo que hago es iniciar todas las variables en “0”  al iniciar la funcion del parseo, luego ponerle  algo como “ if (var != ‘,’) {........} “  es decir, que si en el campo esperado para parsear aparece una coma no asignamos nada a esa variable por lo que se queda en cero.

 

 

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:Procesar string
« Respuesta #3 en: 24 de Octubre de 2017, 01:38:40 »
Gracias a ambos por la respuesta.
Veo que ese problema lo tienen varios.
encontré justo lo que quiero, pero no lo logro adaptar a ccs
https://stackoverflow.com/questions/8705844/need-to-know-when-no-data-appears-between-two-token-separators-using-strtok
strtok_single
Código: C
  1. char *strtok_single (char * str, char const * delims)
  2. {
  3.   static char  * src = NULL;
  4.   char  *  p,  * ret = 0;
  5.  
  6.   if (str != NULL)
  7.     src = str;
  8.  
  9.   if (src == NULL)
  10.     return NULL;
  11.  
  12.   if ((p = strpbrk (src, delims)) != NULL) {
  13.     *p  = 0;
  14.     ret = src;
  15.     src = ++p;
  16.  
  17.   } else if (*src) {
  18.     ret = src;
  19.     src = NULL;
  20.   }
  21.  
  22.   return ret;
  23. }

sample use
Código: C
  1. char delims[] = ",";
  2.   char data  [] = "foo,bar,,baz,biz";
  3.  
  4.   char * p    = strtok_single (data, delims);
  5.  
  6.   while (p) {
  7.     printf ("%s\n", *p ? p : "<empty>");
  8.  
  9.     p = strtok_single (NULL, delims);
  10.   }
output

foo
bar
<empty>
baz
biz
« Última modificación: 24 de Octubre de 2017, 01:41:36 por cvargcal »


 

anything