Not sure if anyone will find this useful. I based my code off another simple string tokenizer that I found on the old QB64 forum. However, that one was too simple for my needs. So, I made some changes.
DIM s AS STRING: s = "Function MyFunc(MyStr As String, Optional MyArg1 As Integer = 5, Optional MyArg2 = 'Dolores Abernathy')"
DIM n AS LONG: n = TokenizeString(s, "(),= ", 0, "''", mytokens())
PRINT n; " tokens parsed for: "; s
DIM i AS LONG
FOR i = LBOUND(mytokens) TO UBOUND(mytokens)
PRINT i; "="; mytokens(i)
SLEEP 1
NEXT
END
' Tokenizes a string to a dynamic string array
' text - is the input string
' delims - is a list of delimiters (multiple delimiters can be specified)
' tokens() - is the array that will hold the tokens
' returnDelims - if True, then the routine will also return the delimiters in the correct position in the tokens array
' quoteChars - is the string containing the opening and closing "quote" characters. Should be 2 chars only
' Returns: the number of tokens parsed
FUNCTION TokenizeString& (text AS STRING, delims AS STRING, returnDelims AS _BYTE, quoteChars AS STRING, tokens() AS STRING)
DIM strLen AS LONG: strLen = LEN(text)
IF strLen = 0 THEN EXIT FUNCTION ' nothing to be done
DIM arrIdx AS LONG: arrIdx = LBOUND(tokens) ' we'll always start from the array lower bound - whatever it is
DIM insideQuote AS _BYTE ' flag to track if currently inside a quote
DIM token AS STRING ' holds a token until it is ready to be added to the array
DIM char AS STRING * 1 ' this is a single char from text we are iterating through
DIM AS LONG i, count
' Iterate through the characters in the text string
FOR i = 1 TO strLen
char = CHR$(ASC(text, i))
IF insideQuote THEN
IF char = RIGHT$(quoteChars, 1) THEN
' Closing quote char encountered, resume delimiting
insideQuote = 0
GOSUB add_token ' add the token to the array
IF returnDelims THEN GOSUB add_delim ' add the closing quote char as delimiter if required
ELSE
token = token + char ' add the character to the current token
END IF
ELSE
IF char = LEFT$(quoteChars, 1) THEN
' Opening quote char encountered, temporarily stop delimiting
insideQuote = -1
GOSUB add_token ' add the token to the array
IF returnDelims THEN GOSUB add_delim ' add the opening quote char as delimiter if required
ELSEIF INSTR(delims, char) = 0 THEN
token = token + char ' add the character to the current token
ELSE
GOSUB add_token ' found a delimiter, add the token to the array
IF returnDelims THEN GOSUB add_delim ' found a delimiter, add it to the array if required
END IF
END IF
NEXT
GOSUB add_token ' add the final token if there is any
IF count > 0 THEN REDIM _PRESERVE tokens(LBOUND(tokens) TO arrIdx - 1) AS STRING ' resize the array to the exact size
TokenizeString = count
EXIT FUNCTION
' Add the token to the array if there is any
add_token:
IF LEN(token) > 0 THEN
tokens(arrIdx) = token ' add the token to the token array
token = "" ' clear the current token
GOSUB increment_counters_and_resize_array
END IF
RETURN
' Add delimiter to array if required
add_delim:
tokens(arrIdx) = char ' add delimiter to array
GOSUB increment_counters_and_resize_array
RETURN
' Increment the count and array index and resize the array if needed
increment_counters_and_resize_array:
count = count + 1 ' increment the token count
arrIdx = arrIdx + 1 ' move to next position
IF arrIdx > UBOUND(tokens) THEN REDIM _PRESERVE tokens(LBOUND(tokens) TO UBOUND(tokens) + 512) AS STRING ' resize in 512 chunks
RETURN
END FUNCTION
The result of running the small snippet of code below confuses me! I would expect Locate to use the first two arguments to set the column and row for text position,
but it uses the first for the vertical row position, and the second, not as the column but as a number to be determined from the font size.
I know, I'm easily confused, but can someone explain this to me?
PHP Code:
Screen _NewImage(1280, 960, 32) f& = _LoadFont("c:\WINDOWS\Fonts\arial.ttf", 28) _Font f& ' Locate 31, 400 ' I would expect this to be an invalid horizontal position Print "This text location is row 31, column 400"; ' but it uses the pixel position, and prints it there! Sleep
After reading through the board and seeing other examples, I thought it be best I will keep the most recent verison on the first post (this post.) Starting a new thread to keep it clean and keeping the old for historical thoughts.
'====================================================================================
'| |
'| Grade Keeper Build 4.1.2 - Resolving issues & adding more user-friendly features!|
'| |
'| Release #6 May 23rd, 2023 |
'| |
'| Additions: #1 - Gradebook Fuctionality! - Clear grades and deletion commands |
'| now fuctional (though I don't like the flow for deletion...) |
'| |
'| Modifications: #1 - All fonts built at start, faster report production! |
'| #2 - Duplication of code moved to a sub MENUFRAME (Title) |
'| #3 - Arial replaced with Arial Narrow due to rendering issue. |
'| #4 - New add student screen. Resolves issues and makes input less |
'| tedious (quicker to do and correct mistakes) |
'| |
'| Current Limitations: #1 - Printed reports limited to windows |
'| #2 = Printed reports limited to 1 page |
'| #3 - Gradebook commands: Add, clear grades, remove |
'| assignment and save and exit (F2, F6, F8, F12) |
'| are fuctional |
'| #4 - Gradebook limited to 20 students and about 20 |
'| assignments (name length dependent) |
'| |
'| Konwn Bugs & Issues: #X - Cancel changing class set will... (Resolved) |
'| #X - Adding an assignment will delay input and cause first |
'| keypress to be loss with GLI (Much less frequent) |
'| #X - Email and address field of add student can overlap |
'| (Resolved with new add student. Old modify student |
'| present until feedback and further testing before |
'| modifying that routinue. |
'| #1 - GLI word wrap issues here and there, will fix later. |
'====================================================================================
The more I use Terry's GLI library, the more powerful and useful I am finding it and how great it works. Do check out the new add student screen (now with mouse support!) to see it in action. Word wrapping is still an issue but it is lower on my list of things to get done. I left the old modify student routinue in place for now, pending on feedback. Then I will also adjust that to be more user-friendly as well!
I believe I got all (or at least most) of the mis-aligned text due to the font change. If you see something funny, please let me know so I can correct it.
Also, though all the files used are in the data.bas file as DATA lines, I also include the raw files in a Dev folder for ease of others to tweak changes.
Finally, I feel like I had to hack the delete assignment command to make it work right. For the life of me, I cannot figure out why the grades were not realigning with the cells after being updated. So after seeing the sub placing them correctly on relaunch, that is exactly what I see a loop up for. To relaunch the gradebook to show the grades right. Don't like such a hack but it works and therefore is staying for now until I have the time to figure out what happened...
Finally, Finally, on a personal note. I am now working (well suppose to starting yesterday) on my master thesis for my master in education. I wanted to get this update out before I unplug for a little bit. I may be a bit slower for a few months but I hope to keep working and improving this program (I do find it relaxing to program ). I feel like I am getting close to calling it a full-on beta here soon!
It looks like SCREEN() function was broken in one of the updates, either that or it's not designed anymore to work in graphic modes. Particularly in 32-bit color.
Below the message it returns 219 and the solid block.
The thing is that I want to read characters from "PRINT USING" output without setting up another hidden screen for it and without creating a temporary file which causes wear and tear on the system due to the thousand calls that my program could potentially generate from it.
After being run my program kept returning an illegal function call because QB64PE doesn't seem to like neither the text coordinates given to it for SCREEN() function. It looks like one cannot set a _FONT and then call SCREEN().
Run this example:
Code: (Select All)
screen _newimage(800, 600, 32)
dim i as integer, amf as long
amf = _loadfont("/usr/share/fonts/liberation/LiberationSans-Regular.ttf", 12)
_font amf
for i = 1 to 120
locate 4, i
print chr$(i + 32);
locate 5, 1
print i; screen(4, i);
next
end
Tested on Linux; replace the _LOADFONT() line with the appropriate for MacOS or Windows. I have tried this with a monospace font, and with optional "MONOSPACE" parameter to _LOADFONT(). This doesn't even go beyond the first position.
So I guess I will have to do without "PRINT USING" formatting toward using _PRINTSTRING or _UPRINTSTRING.
I hope to post fun little bits of code and then try to comment them as fully as I can in attempts to get people new to QB64 up and running faster. Feel free to ask questions to get clarification, I may have screwed up.
_Title "Playing for Charity: 100 dice" ' b+ 2023-05-20
' A game that no one loses!
Randomize Timer
Dim As Long roll, Charity, me, r
For roll = 1 To 100
r = Int(Rnd * 6) + 1
Print " Roll number:"; roll; "is"; r
If r < 5 Then Charity = Charity + r Else me = me + r
Print: Print " I get 5's and 6's:"; me
Print " Charity gets 1, 2, 3, 4's:"; Charity
Print: Print " zzz... press any to continue"
Print
Sleep
Next
Print: Print " Treat ";
If me > Charity Then Print "yourself"; Else Print "Others";
Print " specially well today."
Then I decided if I really wanted to do something Friendly I should comment more fully for Beginners.
So here is same resulting output with lots of comments:
Code: (Select All)
' The following not in original code but a very good habit to get into, it will save you
' from your typos. 3P = Proper Programming Practice :)
Option _Explicit ' This forces you to Dim (or ReDim) your variables before you use them.
' !!! EXCEPTION !!! should you do something like DEFINT A-Z or DEFLNG A-Z then everything
' is automatically. :O
' If the following is in the first lines of your program and you go to save it, QB64 IDE
' will suggest your _Title string for your .bas file name when starting from File > New.
_Title "Playing for Charity: 100 dice" ' b+ 2023-05-20 < 3P author and date with _Title.
' A game that no one loses! < 3P a quick summary or comments. I usually list versions here.
Randomize Timer ' this is here so I don't play the same game over on each run.
' Dim As Long roll, Charity, me, r < 3P originally I had this, but really strong 3P is
' declaring all your variables first 2nd part of Option _Explicit team.
Dim As Long roll ' this tracks the For loop index eg roll number
Dim As Long r ' this is for random to be used to store the dice roll value.
Dim As Long Charity ' variable to store running total points for Charity
Dim As Long me ' variable to store running total points for me.
' I am using Long because I want Integers and Long is easier to type and doesn't take more
' time than Integer Type. So I get a range of over 32,000 with 0 cost.
For roll = 1 To 100 ' the main loop does 100 rolls
r = Int(Rnd * 6) + 1 ' Rnd = 0 to .9999 Multiply by 6 and have 0 to 5.9999
' Take Int(0 to 5.99999) get 0,1,2,3,4,5
' Add 1 for 1 to 6
'
' Print something; < with semi colon ending keeps the print head right where it stops.
' Print something, < with comma tabs the print head right to set column widths
' Print something < nothing after literals or variables moves print head to next line.
' Print will automatically start on next line if can't finish print job on current one.
' Print: < finishes last print line or starts new one by inserting blank line.
Print " Roll number:"; roll; "is"; r ' this first line reporting roll number and roll.
If r < 5 Then Charity = Charity + r Else me = me + r ' this decides if me or Charity
' gets the rolled points
' This reports the running scores and tells Sleep is activated so we have to press a key
' to continue game.
Print: Print " I get 5's and 6's:"; me
Print " Charity gets 1, 2, 3, 4's:"; Charity
Print: Print " zzz... press any to continue"
Print
Sleep
Next ' end of 100 rolls loop onto summary result.
Print: Print " Treat ";
If me > Charity Then Print "yourself"; Else Print "Others";
Print " specially well today."
' the End < 3P if you had GoSubs after this End put an End statement here.
I decided to post the 2nd one here first because A) this is my favorite forum and B) it is likely to be seen more here.
C) I thought it an excellent first post for this thread.
I have been playing around with various ideas but it seems the fonts are loaded differently or displayed differently from 3.6.0 and 3.7.0. Not sure if I have to adjust what I am doing to make it look good again but, personally, I can't accept how they look. Here is a comparision side by side of the two different versions.
You can see the new hotness on the left and the old and busted on the right. Look at the '2's and 'o's. They are cut-off. The problem seems to show itself on lower font sizes where letters are being cut off. (the 3rd line is using a large font and being scaled down as a temp work around but still doesn't look as good as it should if you ask me...)
Here is a quick program ran in 3.7.0
Same code on 3.6.0
You can see in 3.7.0 that 'J' and '2' is being cut (oddly the 'o' isn't) and gets worse the smaller the font size loaded.