|
|
View previous topic :: View next topic |
Author |
Message |
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
Empty field with strok |
Posted: Mon Oct 23, 2017 10:03 pm |
|
|
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
|
|
Posted: Tue Oct 24, 2017 12:47 am |
|
|
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
|
|
Posted: Tue Oct 24, 2017 8:08 am |
|
|
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
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19595
|
|
Posted: Tue Oct 24, 2017 1:40 pm |
|
|
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
|
|
Posted: Tue Oct 24, 2017 3:44 pm |
|
|
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>"); |
|
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Wed Oct 25, 2017 7:12 am |
|
|
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: 9273 Location: Greensville,Ontario
|
|
Posted: Wed Oct 25, 2017 7:25 am |
|
|
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
|
|
Posted: Wed Oct 25, 2017 9:02 am |
|
|
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
|
|
Posted: Wed Oct 25, 2017 4:29 pm |
|
|
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
|
|
Posted: Wed Mar 27, 2019 10:13 am |
|
|
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
|
|
Posted: Wed Mar 27, 2019 12:15 pm |
|
|
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
|
|
Posted: Wed Mar 27, 2019 12:28 pm |
|
|
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
|
|
Posted: Thu Mar 28, 2019 10:41 am |
|
|
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 |
|
|
|
|
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
|