CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Empty field with strok

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

Empty field with strok
PostPosted: Mon Oct 23, 2017 10:03 pm     Reply with quote

I am trying to tokenize a string but I need to know exactly when no data is seen between two tokens. e.g when tokenizing the following string "a,b,c,,,d,e" I need to know about the two empty slots between 'd' and 'e'... which I am unable to find out simply using strtok().

I want write "0" if is empty

Code:
  char str[150];                                                               
   char gprmc[] = "$GPRMC,";
   char tokens[] = ",";
   int i;
   char *p, *lat=0, *latDir=0, *lon=0, *lonDir=0, *time=0,*validity=0,*speed=0,*course=0,*date=0,*variation=0,*east=0,*checksum;
   fgets(str, STREAM_GPS);  ///fprintf(STREAM_USB,"%s\r\n",str);
      if (find_string(str,gprmc)){         //if (strstr(str, gprmc) != 0){
         fprintf(STREAM_USB, "%s", str);
         p = strtok(str, tokens);
         i = 0;
         while(p != NULL){
            switch(i++){
             // !$GPRMC,045103.000,A,3014.1984,N,09749.2872,W,0.67,161.46,030913,,,A*7C
               case 1:  time = p;       break;      //  1   220516     Time Stamp
               case 2:  validity=p;     break;      //  2   A          validity - A-ok, V-invalid
               case 3:  lat = p;        break;      //  3   5133.82    current Latitude
               case 4:  latDir = p;     break;      //  4   N          North/South
               case 5:  lon = p;        break;      //  5   00042.24   current Longitude
               case 6:  lonDir = p;     break;      //  6   W          East/West
               case 7:  speed = p;      break;      //  7   173.8      Speed in knots
               case 8:  course = p;     break;      //  8   231.8      True course
               case 9:  date = p;       break;      //  9   130694     Date Stamp
               case 10: variation = p;  break;      //  10  004.2      Variation
               case 11: east = p;       break;      //  11  W          East/West
               case 12: checksum = p;   break;      //  12  *70        checksum

               default: break;
            }           
            p = strtok(NULL, tokens);
         }


for example: $GPRMC,040146.000,A,,,,W,,,241017,,,A*44
How I can put "0" if the data is empty?

I want similar to
https://stackoverflow.com/questions/8705844/need-to-know-when-no-data-appears-between-two-token-separators-using-strtok
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 24, 2017 12:47 am     Reply with quote

It tells you the answer in those threads:
Use strsep() instead of strtok(). See the link below for strsep() source:
https://code.woboq.org/userspace/glibc/string/strsep.c.html
When translating that code, remember that 'const' in normal C is
different from 'const' in CCS.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Oct 24, 2017 8:08 am     Reply with quote

PCM programmer wrote:
It tells you the answer in those threads:
Use strsep() instead of strtok(). See the link below for strsep() source:
https://code.woboq.org/userspace/glibc/string/strsep.c.html
When translating that code, remember that 'const' in normal C is
different from 'const' in CCS.


Hi, Thanks so much for you answer,
I tried translating but not work

Original

Code:
char *strtok_single (char * str, char const * delims)
{
  static char  * src = NULL;
  char  *  p,  * ret = 0;
 
  if (str != NULL)
    src = str;
 
  if (src == NULL)
    return NULL;
 
  if ((p = strpbrk (src, delims)) != NULL) {
    *p  = 0;
    ret = src;
    src = ++p;
 
  } else if (*src) {
    ret = src;
    src = NULL;
  }
 
  return ret;
}


example
Code:
  char delims[] = ",";
  char data  [] = "foo,bar,,baz,biz";
 
  char * p    = strtok_single (data, delims);
 
  while (p) {
    printf ("%s\n", *p ? p : "<empty>");
 
    p = strtok_single (NULL, delims);
  }


output

foo
bar
<empty>
baz
biz


To CCS

Code:
void main(void){
 while(true){
  char delims[] = ",";
  char data[] = "foo,bar,,baz,biz";
  char *p;
  p= strtok_single (data, delims);

  while (p) {
  fprintf(STREAM_USB, "%s\n", *p ? p : "<empty>");
  p = strtok_single (NULL, delims);
  }
 }
}



Code:
char *strtok_single (char *str, char  *delims){
  static char  *src = NULL;
  char  *p,  *ret = 0;

  if (str != NULL)    src = str;
  if (src == NULL)    return NULL;

p = strpbrk (src, delims)

  if (p != NULL) {
    *p  = 0;
    ret = src;
    src = ++p;
  }
 
 
  else {
 
  if(*src){
    ret = src;
    src = NULL;
  }
  }

  return ret;
}


No work as show the example... work as do it normally

Crying or Very sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Oct 24, 2017 1:40 pm     Reply with quote

Have you got PASS_STRINGS=IN_RAM
This is needed or the "<EMPTY>" won't code as a pointer.

I'd explicitly test for the NULL, rather than relying on this coding as FALSE

(*p!=NULL)?p:"<ENTER>"
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Tue Oct 24, 2017 3:44 pm     Reply with quote

Ttelmah wrote:
Have you got PASS_STRINGS=IN_RAM
This is needed or the "<EMPTY>" won't code as a pointer.

I'd explicitly test for the NULL, rather than relying on this coding as FALSE

(*p!=NULL)?p:"<ENTER>"

mmm I dont undertand if i see NULL value in debug by proteus... and that line has not effect

Code:
fprintf(STREAM_USB, "%s\n", (p!=NULL)?p:"<ENTER>");

Evil or Very Mad Evil or Very Mad
guy



Joined: 21 Oct 2005
Posts: 291

View user's profile Send private message Visit poster's website

PostPosted: Wed Oct 25, 2017 7:12 am     Reply with quote

See the sticky at the top of the forum. Proteus simulator is not welcome here since it is not a good simulator. Can you set up a real PIC and debugger?
temtronic



Joined: 01 Jul 2010
Posts: 9096
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Oct 25, 2017 7:25 am     Reply with quote

yeah Proteus is so full of it's own bugs, I'm NOT surprised it doesn't work as expected...

I supose the FIRST question we have to ask when replying to every (well most) posts is...

Is this REAL hardware or a 'simulation' ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 25, 2017 9:02 am     Reply with quote

Quote:
No work as show the example... work as do it normally

Post the results that you get from the translated code.

You said the good code produces this:
Quote:
foo
bar
<empty>
baz
biz


Post what the bad code produces.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Wed Oct 25, 2017 4:29 pm     Reply with quote

PCM programmer wrote:
Quote:
No work as show the example... work as do it normally

Post the results that you get from the translated code.

You said the good code produces this:
Quote:
foo
bar
<empty>
baz
biz


Post what the bad code produces.


Yes, proteus not too good...
the result is:
bar
baz
biz

No put <empty> , so the code do it the same as do it my code....
mmmm
I read the function strsep() is better, so how i can use this:

Code:
    char *strsep (char **stringp,  char *delim){
     char *begin, *end;
   
    begin = *stringp;
    if (begin == NULL)
      return NULL;
   
    /* Find the end of the token.  */
     end = begin + strcspn (begin, delim);
   
    if (*end)       {
        /* Terminate the token and set *STRINGP past NUL character.  */
        *end++ = '\0';
        *stringp = end;
       }
    else{
       /* No more delimiters; this is the last token.  */
       *stringp = NULL;
    }
     return begin;
   }
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Wed Mar 27, 2019 10:13 am     Reply with quote

Hi, I return to this topic again.

I need control a string with empty space, I need put 0x00 when has not data.
string ="a,b,0,d";

output
a
b
0
d
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed Mar 27, 2019 12:15 pm     Reply with quote

Quote:
I need control a string with empty space, I need put 0x00 when has not data.
string ="a,b,0,d";


The hex value for "0" is 0x30 if i remember my ASCII Table correctly... its not 0x00.

try:
Code:
string ="a,b,\0,d";


BUT be advised, any string operations on this modified string will treat the "\0" as the end of the string (strings are null terminated).
_________________
CCS PCM 5.078 & CCS PCH 5.093
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Wed Mar 27, 2019 12:28 pm     Reply with quote

Thanks, but the idea is parsing the string for separate by token with strtok(), but put any char if found empty space.
cvargcal



Joined: 17 Feb 2015
Posts: 134

View user's profile Send private message

PostPosted: Thu Mar 28, 2019 10:41 am     Reply with quote

Hi, I found this code,

someone suggestion for change to char and not for float?
https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c


Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int split(float *res , char *string , char delim);
 
int split(float *res , char *string , char delim){
int strLen = 0;
int commaCount =0;    // count the number of commas
int commaCountOld =0; // count the number of commas
int wordEndChar = 0;
int wordStartChar = -1;
int wordLength =0;
 
   for(strLen=0; string[strLen] != '\0'; strLen++){     // first get the string length
       if ( (string[strLen] == delim)  || ( string[strLen+1] == '\0' ))        {
           commaCount++;
           wordEndChar = strLen;
        }
       if ( (commaCount - commaCountOld) > 0 )        {
          int aIter =0;
          wordLength = (wordEndChar - wordStartChar);
          char word[55] = "";
          for (aIter = 0;  aIter < wordLength; aIter++)          {
            word[aIter] = string[strLen-wordLength+aIter+1];
          }
 
          if (word[aIter-1] == delim)   word[aIter-1] = '\0';
          //  printf("\n");
          word[wordLength] = '\0';
          res[commaCount-1] = atof(&word[0]);
          wordLength = 0;
          wordStartChar = wordEndChar;
          commaCountOld = commaCount;
        }
  }
  return commaCount;
}
 
  void main(){
    char string[] = "1,,3"; // specify input here
    float array_r[10]; // specify size of float array here
    int totalValues = 0;
    char myDelim = ','; // specify delimiter here
    printf("string => %s \n",&string[0]);
    totalValues = split(&array_r[0] , &string[0], myDelim); // call the function here
    int tokens = 0;
 
    for (tokens = 0 ; tokens < totalValues ; tokens++)    {
      printf("array_r[%d] = %0.f\n",tokens , array_r[tokens]);
    }
 }





output
string => 1,,3
array_r[0] = 1
array_r[1] = 0
array_r[2] = 3
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group