Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 07:19 03 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MM2 Playing with CFunctions(2) CFIELD$

Author Message
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1133
Posted: 05:21am 25 Jul 2017
Copy link to clipboard 
Print this post

Geoff posted his version of a Field$() function.

This was a inspiration to me to write a CFunction for that purpose (just a exercise).

What can I do with this?
From MMBasic manual V5.04.04 p.75. Rem.: It is not (yet) part of MMBasic! (modified text)
  Quote  FIELD$( str$, field, delim$)

Extract a substring (ie, field) from 'str$'. Each is separated by the character in the string 'delim$' and the field number to return is specified by 'field' (the first field is field number 1).
...
This function is useful for splitting apart comma-separated-values (CSV) in data streams produced by GPS modules and test equipment. For example:
PRINT FIELD$("aaa,bbb,ccc", 2, ",")
Will print the string "bbb"


You can download the demo code and c source here 2017-07-25_150235_CField$_CFunction.zip . Any questions, comments and suggestions highly welcome!

All code provided without any warranty but reasonable testet.


'
' File Cfield.bas written 25-Jul-2017 14:32:42
'
' Usage: a$=Cfield$("one,two,three",2,",") or Cfield$("one,two,three",2)
' returns: "two"
' The delimiter character is optional and can be almost any char
' eg "," or ";" or ":" or "/" or "x" or " " ... (default: ",")
'
' It leaves leading and trailing spaces untrimmed
' Please use LTrim & RTrim for that if you need it(CFunctions)
'
' One call of Cfield$() takes about 0,3ms
'
' For the TBS by twofingers (2017), Public Domain
'

CFunction Cfield$(string,integer,string) string
00000000
27BDFFD8 AFBF0024 AFB40020 AFB3001C AFB20018 AFB10014 10C00003 AFB00010
10000002 80C60001 2406002C 90B30000 24900001 90850000 02052821 0080A021
02008821 10000008 24120001 14660005 26020001 26910001 26520001 325200FF
0200A021 00408021 12050005 0272102B 5040FFF6 82030000 10000021 3C029D00
26910001 3C029D00 8C420040 0040F809 24040100 0253902B 16400011 A0400000
0200A021 1260000F 8FBF0024 02911823 A0430000 0291182B 1460000A 8FBF0024
00401821 24630001 92240000 A0640000 26310001 0291202B 5080FFFB 24630001
8FBF0024 8FB40020 8FB3001C 8FB20018 8FB10014 8FB00010 03E00008 27BD0028
8C420040 0040F809 24040100 1000FFE5 A0400000
End CFunction


C source
char* field$(char* inputstr, long long* sel_field, char* delimiter_char)
{
char delim;
if (delimiter_char == NULL){ // if delimiter not provided
delim = ','; // default char ','
}else{
delim = delimiter_char[1]; // BASIC string character
}

unsigned char sel; // if selected field number not provided
if(sel_field == NULL) { // Error!
sel = 0;
}else{
sel = (unsigned char)*sel_field; // selected field number
}

unsigned char delim_count=1; // counter for delimiters
unsigned char len = inputstr[0]; // BASIC string length
char* p_istr=inputstr+1; // set pointer to the string content
char* p_astr=inputstr+1; // begin pointer
char* p_estr=inputstr; // end pointer

char* p_ret; // pointer to return string
char* p_tmp; // temp string pointer

len++;
while(--len && (delim_count <= sel)){ // count fields with trailing
// delimiters
if (*p_istr++ == delim){
p_astr=p_estr+1;
p_estr=p_istr-1;
delim_count++;
}
}

if(!len){ // last field has no delimiter
p_astr=p_estr+1;
p_estr=p_istr;
}

p_ret = GetTempMemory(256);
*p_ret = '\0'; // Store BASIC (trimmed) string length
if (!(delim_count < sel) && sel){ // if sel_field not out of range
p_tmp = p_ret; // Copy pointer to ret string
*p_ret = p_estr - p_astr; // store string length
while (p_astr <= p_estr) {// Copy the string, starting from the first char
*++p_tmp = *p_astr++;
}
}
return p_ret;
}

void main(){}


Regards
MichaelEdited by twofingers 2017-07-26
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1985
Posted: 09:21am 25 Jul 2017
Copy link to clipboard 
Print this post

top man! - you are getting prolific!
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 11:16am 25 Jul 2017
Copy link to clipboard 
Print this post

@Geoffg or @matherp
Calling GetTempMemory() without a corresponding FreeMemory() is not a good idea?
Unless the system calls FreeMemory() in the background, which I don't think is the
case, a programmed loop of this (ltrim()/rtrim() functions too) would use all available RAM in approx. 200 calls!

Miss you George
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 11:33am 25 Jul 2017
Copy link to clipboard 
Print this post

GetTempMemory() vs GetMemory()

One needs FreeMemory the other doesn't - guess which is which
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 04:50pm 25 Jul 2017
Copy link to clipboard 
Print this post

How many guesses do I get?
Miss you George
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 10:36pm 25 Jul 2017
Copy link to clipboard 
Print this post

GetTempMemory()Edited by MicroBlocks 2017-07-27
Microblocks. Build with logic.
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1133
Posted: 11:55pm 25 Jul 2017
Copy link to clipboard 
Print this post

I forgot to mention that this CField$() function (MM2) requires MMBasic V5.2 or better.

@CaptainBoing
Thanks, I hope so!

@led-bloon
  Quote  … a programmed loop of this (ltrim()/rtrim() functions too) would use all available RAM in approx. 200 calls!
If you run my little demo program you will see it works for 50000 calls without issues.

But I'm always happy about the people who read the code and ask questions.
Questions are the key to wisdom!

Michael



 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1985
Posted: 12:50am 26 Jul 2017
Copy link to clipboard 
Print this post

Hi Twofingers, a worthy addition to your string handling repertoire, fancy a go at the REPLACE function?

Whereas these functions are fairly easily "do-able" in MMBasic, your versions are really valuable contributions for compactness and speed and a great contribution.

http://www.fruitoftheshed.com/MMBasic.VB-Work-a-like-REPLACE-Function.ashx?HL=replace

Edited by CaptainBoing 2017-07-27
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1133
Posted: 01:28am 26 Jul 2017
Copy link to clipboard 
Print this post

  CaptainBoing said   Hi Twofingers, a worthy addition to your string handling repertoire, fancy a go at the REPLACE function?

Whereas these functions are fairly easily "do-able" in MMBasic, your versions are really valuable contributions for compactness and speed and a great contribution.

That's something that was already on my agenda, but I thought it's maybe too easy!

Thanks for your suggestion! Coming soon ...

Regards
Michael
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024