VAL and MID non compatable BASIC

Forums: 

? "VAL(*99*) = ";val("99")
? "VAL(*99 bottles of beer*) = "; VAL("99 bottles of beer") ' < should be 99
?
for
i = 1 to 10
? i, MID("tooShort", i, 1) '< (EDIT: 2017-07-27) error / crash at i = 9 (or i = 0)

' SHOULD just return "" if out of range
next
pause


Tested with QB64 and noticed discrepancies when translating JB, LB, LBB code.

This came up while trying to duplicate nicely brief eval subroutine.

I see your issue with VAL - it should "stop reading the string at the first character it can't recognize as part of a number. ". I'll fix that for the next update.

But not sure about your issue with MID, for the various versions of SB that I tried I get the error:

String: Index out of range (9)

Isn't that the correct result?

I have tested and confirmed that Just Basic (and Liberty Basic and LB Booster), QB64, and Free Basic with mid$(test$, i, 1), they all return "" when i is out of range with test. This is nice not to crash a program by that. These, like SmallBASIC, claim to be close inheritors of Quick Basic standard. Further I am certain that BBC's MID works the same.

SdlBasic is the only one I found that does not. Something about variable typing? I wonder.

I doubt a change will render any old code unusable.

I just noticed I wrote the example incorrectly in the OP, I said it does not crash.
I am sorry, I meant to say, it SHOULD not crash when i goes out of range.

The following commands also share the issue you reported with MID where an invalid index causes an error:

LEFT, RIGHT, REPLACE, INSTR, RINSTR

Do you know what the behaviour is with these commands in other BASICs?

Cheers,
Chris

To sum up the tests and references for FB, QB64, JB, and SdlBasic, they do NOT halt execution of a program to report that the text index requested is "out of bounds" of the text.

Ha! I learned a couple of minor differences between all 5 of my favorite BASIC's. Will I remember which does what? Probably not.

Kudos to SmallBASIC for very comprehensive string handling functions!

replace not found, InStrRev found that maybe serve as Rinstr

FB test code:
Print(left("test", 10)) ' > test
Print(right("test", 10)) ' > test
Print(instr(10, "test","t")) ' > 0
Print(instr(-5, "test", "t")) ' > 0
Print(InStrRev("test", "t", 10)) '> 0 note the different location for start
Sleep

Code above probably sums up the following from the FB manual:

lookup Left:
Description

Returns the leftmost n characters starting from the left (beginning) of str. If str is empty, then the null string ("") is returned. If n <= 0 then the null string ("") is returned. If n > len(str) then the entire source string is returned.
'===========================================================
lookup Right:
Description

Returns the rightmost n characters starting from the right (end) of str. If str is empty, then the null string ("") is returned. If n <= 0 then the null string ("") is returned. If n > len(str) then the entire source string is returned.
'===========================================================

lookup InStr:
Description

Locates the position of the first occurrence of a substring or character within a string. In the first form of InStr (without start parameter), the search begins at the first character.

Zero (0) is returned if: either substring is not found, either str or substring are empty strings, or start < 1.

If the Any keyword is specified, InStr returns the first occurrence of any character in substring.

Example

' It will return 4
Print InStr("abcdefg", "de")

' It will return 0
Print InStr("abcdefg", "h")

' It will search for any of the characters "f", "b", "c", and return 2 as "b" is encountered first
Print InStr("abcdefg", Any "fbc")

Dim test As String
Dim idx As Integer

test = "abababab"
idx = InStr(test, "b")

Do While idx > 0 'if not found loop will be skipped
Print """b"" at " & idx
idx = InStr(idx + 1, Test, "b")
Loop
'=========================================================

found InStrRev

Description

Locates the position of the last occurrence of a substring or character within a string. If start parameter is not given or is -1, the search begins at the last character.

Zero (0) is returned if: either substring is not found, or either str or substring are empty strings, or start is less than 1 (except for -1), or start is greater than the length of str.

If the Any keyword is specified, InStrRev returns the last occurrence of any character in substring.

Example

' It will return 4
Print InStrRev("abcdefg", "de")

' It will return 0
Print InStrRev("abcdefg", "h")

Dim test As String
Dim idx As Integer

test = "abababab"
idx = InStrRev(test, "b")

Do While idx > 0 'if not found loop will be skipped
Print """b"" at " & idx
idx = InStrRev(Test, "b", idx - 1)
Loop

Neither Rinstr (nor instrRev found) nor Replace

QB64 test Code:
PRINT (LEFT$("test", 10)) ' > test
PRINT (LEFT$("test", -5)) ' > blank (no error)
PRINT (RIGHT$("test", 10)) ' > test
PRINT (RIGHT$("test", -5)) ' > blank (no error)
PRINT (INSTR(10, "test", "t")) ' > 0
PRINT (INSTR(-5, "test", "t")) ' > 1
SLEEP

This probably sums up the following from wiki reference:

LEFT$
The LEFT$ string function returns a part of a STRING from the start a set number of places.

Syntax:
LEFT$(stringvalue$, numberofcharacters%)

The string value can be any string of ASCII characters as a string variable.
If the number of characters exceeds the string length the entire string is returned.
Number of characters cannot be a negative value.
LEFT$ returns always starts at the first character of the string, even when a space. LTRIM$ can remove leading spaces.
'=========================================================

RIGHT$
The RIGHT$ function returns a set number of characters in a STRING variable starting from the end and counting backwards.

Syntax:
RIGHT$(stringvalue$, numberofcharacters%)

The string value can be any string of ASCII characters as a string variable.
If the number of characters exceeds the string length(LEN) the entire string is returned.
Number of characters cannot be a negative value.
RIGHT$ returns always start at the last character of the string, even if a space. RTRIM$ can remove ending spaces.
'==========================================================

The INSTR function searches for the first occurance of a search STRING within a string and returns the position it was found.

Syntax:
position% = INSTR([start%,] basestring$, searchstring$)

The basestring position of the first character of the searchstring is returned by the function if found.
Position returned will be 0 if the search found no matches in the base string.
Start INTEGER position is optional. Must be at least 1 (start of a string) when used or an Illegal function call will occur.
The Start position is useful when making multiple searches in the same string. Otherwise it starts at the beginning again!
Base string and search string are any literal or variable STRING values.
The search string should be smaller than the base string!
Non-zero position return values can be used as a new start position by adding 1 to re-search the base string.
In a loop, INSTR can search an entire file for occurences of certain words. See the MID$ statement example.

JB 5 commands: Neither Rinstr (nor instrRev) nor Replace found.

JB code test almost same as QB64 (except no SLEEP allowed) :
PRINT (LEFT$("test", 10)) ' > test
PRINT (LEFT$("test", -5)) ' > blank (no error)
PRINT (RIGHT$("test", 10)) ' > test
PRINT (RIGHT$("test", -5)) ' > blank (no error)
PRINT (INSTR(10, "test", "t")) ' > 0
PRINT (INSTR(-5, "test", "t")) ' > 1

Which probably sums up the following from JB Help file:

LEFT$(string, number)
Description:
This function returns from string the specified number of characters starting from the left. If string is "hello there", and number is 5, then "hello" is the result.

Usage:
[retry]
input "Please enter a sentence>"; sentence$
if sentence$ = "" then [retry]
for i = 1 to len(sentence$)
print left$(sentence$, i)
next i

Produces:
Please enter a sentence>That's all folks!
T
Th
Tha
That
That'
That's
That's_
That's a
That's al
That's all
That's all_
That's all f
That's all fo
That's all fol
That's all folk
That's all folks
That's all folks!

Note: If number is zero or less, then "" (an empty string) will be returned. If number is greater than or equal to the number of characters in string, then string will be returned.
'===========================================================

RIGHT$(string, number)
Description:
This function returns a sequence of characters from the right hand side of string using number to determine how many characters to return. If number is 0, then "" (an empty string) is returned. If number is greater than or equal to the number of characters in string, then string will itself be returned.

Usage:
print right$("I'm right handed", 12)

Produces:
right handed

And:
print right$("hello world", 50)

Produces:
hello world
'=========================================================

(notice JB reverses starting place)

INSTR(string1, string2, starting)

Description:
This function returns the position of string2 within string1. If string2 occurs more than once in string1, then only the position of the leftmost occurance will be returned. If the starting parameter is included, then the search for string2 will begin at the position specified by starting.

Usage:
print instr("hello there", "lo")
produces: 4

print instr("greetings and meetings", "eetin")
produces: 3

print instr("greetings and meetings", "eetin", 5)
produces: 16

If string2 is not found in string1, or if string2 is not found after starting, then INSTR( ) will return 0.

print instr("hello", "el", 3)
produces: 0

and so does:
print instr("hello", "bye")

I tested:
print instr("hello", "o", 10)
returns: 0
'=======================================================

SdlBasic 5 commands: instrRev or likes not found

reference is very terse so ran tests"

sdlbasic code:
prints(left("test", 10)) ' > test
prints(right("test", 10)) ' > test
prints(instr(10, "test","t")) ' > 0
prints(instr(-5, "test", "t")) ' > 1
prints(replace(3, "test", "x")) '> tesx ??? bug!
prints(replace(10, "test", "x")) '> test
prints(replace(-5, "test", "x")) '> xest
waitkey(32)


? replace("test", 3, "x", 1) 'exactly what I expect
? "*";replace("test", 3, "x", 10);"*" 'exactly what I expect even when 10 is off the charts
'? replace("test", 13, "x", 1) '> error programs stops to tell me, well I hope you know what I think it should be ;)
pause