Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
INKEY$ doesn't work with fixed length strings
#11
(07-30-2024, 04:58 PM)bplus Wrote:
Quote:It would be also nice, that we have new LEN() function that returns the actual length of the string.

What! ? did someone not renew our license to Len()

Quote:Wouldn't _KEYHIT simply be easier for this?

yeah! and do you know that under IDE Menu > Tools > Insert Quick Keycode
you can insert the Keycode quickly, no number lookup!

Can notepad++ do that? ;-))

Or, even easier.... CTRL-K and then hit the key.   It's a shortcut I use all the time with _KEYHIT and _KEYDOWN.   Wink
Reply
#12
(07-30-2024, 03:53 PM)SMcNeill Wrote: Wouldn't _KEYHIT simply be easier for this?

INKEY$ returns a 1 or 2-byte string value for user input.  _KEYHIT returns that *exact* same value, except in Integer form, rather than string.  You can easily convert between the two with the MKI$ and CVI commands.   It just seems to me if you're always going to be dealing with 2-byte strings, that it'd probably just be more efficient overall to just use the integer values.  There's always extra overhead when dealing with strings, and they're always slower than integers to process and handle, so I'd honestly just _KEYHIT over INKEY$.
You are correct, I mentioned this at the beginning of the post. 

I'm not so worried about the functionality of INKEY$ as much as the utility of fixed length strings. I just wished they behaved like normal strings.

For example, using LEN returns size of memory allocated not the last character in the string. Perhaps that is how LEN works for variable length strings under the hood, but the end user sees it as the last character. I'm not saying this wrong, but It would be nice to have a function that returns the actual length of string.

Concatenation is problematic, because it puts the two blocks of memory together and calls it a day, instead finding the actual last character of the first string and then adding on to that.

Another oddity is fixed length strings are initialized with CHR$(0), but as soon as you assign it a string, it fills the void with spaces. If it were left as CHR$(0) then it would be easier to roll our own LEN function.

INKEY$ is just a demonstration of the limitations that fixed strings have.

Here is a sample of what I'm talking about.

Code: (Select All)
TYPE tt
a AS STRING * 8
b AS STRING * 8
END TYPE

DIM t AS tt
PRINT "t.a = "; t.a
PRINT "t.b = "; t.b
PRINT
PRINT "LEN() before being assigned:"; LEN(t.a), LEN(t.b)
PRINT "Actual Length:"; sLen(t.a), sLen(t.b)
PRINT
PRINT "This is what it is filled with."
FOR i = 1 TO LEN(t.a)
PRINT ASC(MID$(t.a, i, 1)); " ";
NEXT
PRINT

t.a = "01234"
t.b = "56789"
PRINT
PRINT "t.a = "; t.a
PRINT "t.b = "; t.b
PRINT

PRINT "LEN() after being assigned:"; LEN(t.a), LEN(t.b)
PRINT "Actual Length:"; sLen(t.a), sLen(t.b)
PRINT
PRINT "This is what it is filled with."
FOR i = 1 TO LEN(t.a)
PRINT ASC(MID$(t.a, i, 1)); " ";
NEXT
PRINT
PRINT
PRINT "Concatenation"
PRINT t.a + t.b
PRINT
PRINT "Modified Concantenation"
PRINT LEFT$(t.a, sLen(t.a)) + t.b



FUNCTION sLen (s AS STRING)
DIM l AS LONG: l = LEN(s)
' How is this supposed to know if the last space was assigned or put there by QB64
DO WHILE (ASC(MID$(s, l, 1)) = 32 OR ASC(MID$(s, l, 1)) = 0) AND l > 1
  l = l - 1
LOOP
' Again, how is this supposed to know if the last space was assigned or put there by QB64
IF (ASC(MID$(s, l, 1)) = 32 OR ASC(MID$(s, l, 1)) = 0) THEN l = l - 1
sLen = l
END FUNCTION
Reply
#13
I dunno.  The current behavior makes perfect sense to me.   If this was a datafile on a disk, the way it'd behave is:

Before ever reading any information from that file, it's all nul -- chr$(0).

You read 5 bytes from that file, but this is a set length 8 byte record.   You get those 5 bytes + 3 blank spaces.

The LEN should always report 8, as the reserved length of space in memory is 8 bytes.   If you want to know how many characters that are that aren't leading or trailing CHR$(0) or CHR$(32), then you need to write a routine to filter those out yourself, just as you would if you only wanted numeric numbers from a customer's address.  "1234 Fartwood Lane.".... filter out anything not a 0 to 9, and you're left with "1234".

The way it's behaving seems to make perfect sense to me.  Maybe I'm just the odd one here?
Reply
#14
Is that North Fartwood or South Fartwood?

Pete Big Grin

- Healthy hint: Try removing pine trees from your diet.
Reply
#15
I'm going to disagree with you Steve. I've plead my case, this is not a poop hill I'm going to die on.
Reply
#16
(07-31-2024, 02:35 PM)justsomeguy Wrote: I'm going to disagree with you Steve. I've plead my case, this is not a poop hill I'm going to die on.

So let me ask: 

Code: (Select All)
DIM a AS STRING * 8
a = "12345"

FOR i = 1 to 10
   PRINT a;
NEXT

In the above, how many instances of a is going to appear on a line with a width of 40 characters?   How much space does each of those strings take on the screen?  Are they all going to be side-by-side, as "12345123451234512345"?  Or would you expect them to be, "12345   12345   12345   12345   "?

The answer there should be what you'd expect LEN() to return for you.
Reply
#17
Code: (Select All)
DIM a AS STRING * 8
DIM b AS STRING
a = "12345"
b = "12345"

FOR i = 1 TO 10
PRINT a;
NEXT

FOR i = 1 TO 10
PRINT b;
NEXT

I believe that these should have the same result.

The excess memory is there for use, but not filled with spaces.
Reply
#18
If wishes were fishes...

If QB64 were consistent there would be little compatibility with the past. That would piss off allot of die-hard fans.

This problem seems easily summountable IMHO but not by changing how QB64 functions, maybe I am missing something (wouldn't be the first time, not exactly a virgin to blundering but sometimes one learns something new).

Wouldn't what justsomeguy is suggesting change how old code functions?
b = b + ...
Reply
#19
The project standard has always been heavily weighed on maintaining QuickBASIC compatibility. The way around such issues is to create a new keyword that differs in action, much like _KEYHIT vs INKEY$.

I vaguely remember once having an issue with a very early QB64 version where my QuickBASIC program ran correctly on the previous version but not on the next update. The update was reworked to make it compatible again. There is something, much more recent, that I also can't recall completely, where a change in something, I think involving functions, was made. I believe there was some disclosure, in that build or the wiki, to that effect. I complain here about old age, but I can't remember what century I was born.

Pete
Reply
#20
The change in functions that I remember was when we broke a hell of allot of old code which was why we jumped the version number to 2.0, honestly did it really help anything? Sure it made us consistent to theorectical way a programming language should use the function name.

We were using the name as a temp variable but it should have been calling itself as recursive code or erroring because not using proper parameters in call to itself. Something like that, jog your memory any?

So yeah to me it's big deal breaking compatibility.

If you want, I can rant about another break kind of swept under the carpet about color constants I am still fixin, no, better not. Smile
b = b + ...
Reply




Users browsing this thread: 2 Guest(s)