Author Topic: FUNCTION to return STRING or STRING ARRAY  (Read 5788 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
FUNCTION to return STRING or STRING ARRAY
« on: March 07, 2021, 11:35:11 am »
Not sure if this has been asked or if I asked it (LOL),
QB64 seems to be one of the few that cannot return a string value from a function

example
Did not see a qb64 native of this routine, so I made one (there is a catch)

Code: QB64: [Select]
  1. SUB SPLITSTR (HAYSTACK AS STRING, NEEDLE AS STRING) ' SPLITS STRING BASED ON a delimeter into an array
  2.     DIM CNT AS INTEGER
  3.     HAYSTACK = _TRIM$(HAYSTACK)
  4.  
  5.     CNT = 1
  6.     FOR I = 1 TO LEN(HAYSTACK)
  7.         IF MID$(HAYSTACK, I, 1) <> NEEDLE THEN
  8.             SPLIT_EXT(CNT) = SPLIT_EXT(CNT) + MID$(HAYSTACK, I, 1) '<-- this has to be a global or it wont work
  9.         ELSE
  10.             CNT = CNT + 1
  11.         END IF
  12.  
  13.     NEXT

This is basically an EXPLODE from PHP
Problem, is I like this and want to put it in my UTILS.BI, but this is not possible as a function. Functions only return a numeric value not a string. Is there a way to make this work without a SHARED?
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #1 on: March 07, 2021, 11:39:17 am »
A function can return a string. What you have there is a sub, which doesn't return any value. Put the type suffix of the string in your function declaration

Code: QB64: [Select]
  1.     Function String.PadLeft$ (padString As String, totalWidth As Integer, paddingChar As String)
  2.         padString = String$(totalWidth - Len(padString), paddingChar) + padString
  3.         String.PadLeft = padString
  4.  
  5.     Function String.PadRight$ (padString As String, totalWidth As Integer, paddingChar As String)
  6.         padString = padString + String$(totalWidth - Len(padString), paddingChar)
  7.         String.PadRight = padString
  8.  
  9.     Function String.FormatPercent$ (number As Double)
  10.         number = number * 100
  11.         String.FormatPercent = _Trim$(Str$(number)) + "%"
  12.  
  13.     Function String.Replace$ (a As String, b As String, c As String)
  14.         j = InStr(a, b)
  15.         If j > 0 Then
  16.             r$ = Left$(a, j - 1) + c + String.Replace(Right$(a, Len(a) - j + 1 - Len(b)), b, c)
  17.         Else
  18.             r$ = a
  19.         End If
  20.         String.Replace = r$
  21.  
  22.     Function String.Remove$ (a As String, b As String)
  23.         Dim c As String
  24.         c = ""
  25.         j = InStr(a, b)
  26.         If j > 0 Then
  27.             r$ = Left$(a, j - 1) + c + String.Remove(Right$(a, Len(a) - j + 1 - Len(b)), b)
  28.         Else
  29.             r$ = a
  30.         End If
  31.         String.Remove = r$
« Last Edit: March 07, 2021, 11:47:42 am by SpriggsySpriggs »
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #2 on: March 07, 2021, 11:44:09 am »
You can read up on how to make a function here:
https://www.qb64.org/wiki/FUNCTION
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #3 on: March 07, 2021, 12:14:08 pm »
HI!!
thanks for the fast reply

I did read that, and every time I tried to return a string it got an error

Quote
A FUNCTION block statement is used to create a function procedure to return a calculated value to a program.

Key word for me was "calculated value" of course I naturally thought numeric . :-)

OK lemme check out what you did. I did notice there is a string $ after the function name. was that the missing link?



EDIT:
O, to clarify, I understand that was a sub, it could not make it work with a function LOL
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #4 on: March 07, 2021, 12:15:17 pm »
Yes. If you do not specify a type suffix after the function name then it defaults to the type of SINGLE, which is numeric.
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #5 on: March 07, 2021, 12:20:48 pm »
OK those routines area all old school and can be done with mid$, left$, right$ , but they do convey an excellent example of returning a string
What I am trying to do is split strings based on a delimiter - much like the PHP version (and I think js, pascal and a few others have one too)

Quote
https://www.php.net/manual/en/function.explode.php

this will return an array:
Code: PHP: [Select]
  1. $some_string = "a;b;c;d";
  2. $d = explode(some_string, ";");
  3.  
  4. this will give
  5. $d[1] = "a";
  6. $d[2] = "b";
  7. $d[3] = "c";
  8.  
etc...
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Marked as best answer by xra7en on March 07, 2021, 07:38:44 am

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #6 on: March 07, 2021, 12:28:37 pm »
Code: QB64: [Select]
  1.     Redim As String D(0)
  2. String.Split "a;b;c;d", ";" D()
  3.     For y = 0 To UBound(D)
  4.         Print y, D(y)
  5.     Next
  6. Sub String.Split (Expression As String, delimiter As String, StorageArray() As String)
  7.         Dim copy As String, p As Long, curpos As Long, arrpos As Long, dpos As Long
  8.         copy = Expression
  9.         If delimiter = " " Then
  10.             copy = RTrim$(LTrim$(copy))
  11.             p = InStr(copy, "  ")
  12.             While p > 0
  13.                 copy = Mid$(copy, 1, p - 1) + Mid$(copy, p + 1)
  14.                 p = InStr(copy, "  ")
  15.             Wend
  16.         End If
  17.         curpos = 1
  18.         arrpos = UBound(StorageArray)
  19.         dpos = InStr(curpos, copy, delimiter)
  20.         Do Until dpos = 0
  21.             StorageArray(UBound(StorageArray)) = Mid$(copy, curpos, dpos - curpos)
  22.             ReDim _Preserve StorageArray(UBound(StorageArray) + 1) As String
  23.             curpos = dpos + Len(delimiter)
  24.             dpos = InStr(curpos, copy, delimiter)
  25.         Loop
  26.         StorageArray(UBound(StorageArray)) = Mid$(copy, curpos)
  27.         ReDim _Preserve StorageArray(UBound(StorageArray)) As String
  28.     End Sub
« Last Edit: March 07, 2021, 12:31:54 pm by SpriggsySpriggs »
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #7 on: March 07, 2021, 12:38:32 pm »
O thanks that might work..


bummer side, now I gotta research that and see how that works.


I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #8 on: March 07, 2021, 12:44:07 pm »
There is probably an easier way of doing it but I've just been using that one all along. I might look into it again and see if I can make one that is far simpler. That code originally came from Steve, I believe. I made some minor edits but the credit goes to him for that
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #9 on: March 07, 2021, 12:53:28 pm »
it is actually pretty slick. I did not know you can put an array inside the parameters section. gonna have to tinker with that.
also I noticed this is not a function - which is fine, as my ultimate goal is just to produce an array made up of a delimited string. thanks for the inspiration
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #10 on: March 07, 2021, 12:54:49 pm »
Yeah, currently we cannot return an array directly. The way to get around that is passing an array and filling it.
Shuwatch!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #11 on: March 07, 2021, 01:05:19 pm »
Here is what I came up with: WORKS PERFECT at least for my app, did not have to redim
Code: QB64: [Select]
  1. SUB EXPLODE (HAYSTACK AS STRING, NEEDLE AS STRING, EXPLODED_ARY() AS STRING)
  2.     DIM CNT AS INTEGER
  3.     HAYSTACK = _TRIM$(HAYSTACK)
  4.  
  5.     CNT = 1
  6.     FOR I = 1 TO LEN(HAYSTACK)
  7.         IF MID$(HAYSTACK, I, 1) <> NEEDLE THEN
  8.             EXPLODED_ARY(CNT) = EXPLODED_ARY(CNT) + MID$(HAYSTACK, I, 1)
  9.         ELSE
  10.             CNT = CNT + 1
  11.         END IF
  12.     NEXT
  13.  

In the app I call it via:

Code: QB64: [Select]
  1.  EXPLODE CONSOLE.Extentions, CHR$(32), SPLIT_EXT()    

THANKS A MILLION!!!!
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #12 on: March 07, 2021, 01:07:08 pm »
How many elements are you giving your array when you declare it? The reason REDIM was used in the version I gave you is because of dynamic sizing.
Shuwatch!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #13 on: March 07, 2021, 01:17:11 pm »
Yeah here is a fine splitter and you split to Dynamic array ie REDIM instead of DIM to start the array Plus any lower eg, Lbound 0 or 1: REDIM myArray$ (0) or REDIM myArray$( 1 to 1) for base 1 array such that the number of items in it = it's UBOUND(myArray$) after Split:
https://www.qb64.org/forum/index.php?topic=1607.0

Handy for tons of things like splitting a fileStr$ by Chr$(13) + Chr$(10)  for an array of File lines.

Use Astrings (Array like Strings = long string Joined by common delimiter$) in Type variable for Array like functioning.
« Last Edit: March 07, 2021, 01:21:23 pm by bplus »

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: FUNCTION to return STRING or STRING ARRAY
« Reply #14 on: March 07, 2021, 01:21:15 pm »
How many elements are you giving your array when you declare it? The reason REDIM was used in the version I gave you is because of dynamic sizing.

Just 10, the app doesnt need any more than 5 though. but works
o ya and the redim caused a duplicate error in the sub.. may have to re look at that, but for not it works as needed.
« Last Edit: March 07, 2021, 01:22:47 pm by xra7en »
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!