BBC BASIC for Windows
Programming >> BBC BASIC language >> Working with strings
http://bb4w.conforums.com/index.cgi?board=language&action=display&num=1427764031

Working with strings
Post by CharlesB on Mar 6th, 2015, 10:06pm

Below are two issues;

I have been working with the "files" examples programs and have come to an impasse. I have learned how to write to serial files, but reading them, from the Example files and from the help documentation has given me some challenges.

Here is an example of reading the file.
My problem is when the program executes the line "local fnum"
I get a syntax error.

The example program "F-WERSER1 has the following code.

rem F-WESER1
:
rem EXAMPLE OF WRITING TO THE END OF A SERIAL DATA FILE
:
rem This program opens a file and sets PTR to the end
rem before writing more data to it.
:
rem A function is used to open the file.
:
oscli "CD """+@usr$+""""
:
phonenos=fn_openend("PHONENOS.DAT")
print "File Name PHONENOS.DAT Opened as Channel "laughhonenos
print
repeat
input "Name ? " name$
if name$="" then proc_end
input "Phone Number ? " phone$
print
print#phonenos,name$,phone$
until false
:
def proc_end
close#phonenos
end
:
:
rem Open the file 'AT END'.
:
rem If the file does not already exist, it is created
rem with OPENOUT. PTR# is left at zero and the file
rem number is returned. If the file exists, PTR# is
rem set to the end and the file number returned.
:
def fn_openend(name$)
local fnum
fnum=openup(name$)
if fnum=0 then fnum=openout(name$): =fnum
ptr#fnum=ext#fnum
=fnum
*********************************************

I modified this file for my program; it has all string variables and they represent percentage increases in pricing, but when I add this code to a larger pricing program, I get a syntax error when it executes the "local fnum"

I do not get the error if the program stands alone. I only get the error when I add the code to a larger program. I have put the function at the end of the larger program code, but still get the error.

I can't understand why.
I have looked up the "local" statement and I am not at a place where I can understand the description of it.

I don't even know what the "stack" is so it's pretty Greek to me.

1) can anyone help me here in finding out why I have a syntax error?
and what I can do to fix it?


2) on the other hand, I have eliminated the problem by just remming out the local data$, byte$,byte code and just directly reading the one-line file that I want.

I used input#compat, mystring$

This worked for me!
mystring is simply one line of a comma delimited file where each character represents a percentage.

It can read something like 5,8,6,2,4,5,10,5,5,
All I need to do is to separate the numerals from the commas.

So, I want to get an array or set of strings where:
A$(1) = "5"
A$(2) = "8" etc.


I know that I should do this by left$, mid$, right$, arrays, etc, and for the life of me I have been unsuccessful. I've been at it all day just determined to beat this thing and learn something.

But now, I'm just asking for some help. I know that this is a simple thing to do, but I just can't do it.

Thank you anyone for some help.
Charles
Re: Working with strings
Post by rtr2 on Mar 6th, 2015, 10:50pm

on Mar 6th, 2015, 10:06pm, CharlesB wrote:
My problem is when the program executes the line "local fnum" I get a syntax error.

That is, to say the least, extremely strange. I cannot think of any circumstance in which LOCAL fnum would give rise to a Syntax Error. If LOCAL was misspelt it would result in a Mistake error; if it was used in the 'main program' instead of a function it would result in a Not in a FN or PROC error.

It's conceivable that the Syntax Error arises from a bug in v6.00a, which is one of my great fears, so please persevere in discovering the cause. Are you able to post some self-contained code which I can run that demonstrates this behaviour? If all else fails, send me the entire program as an email attachment (or upload it somewhere and send me a link).

Quote:
on the other hand, I have eliminated the problem by just remming out the local data$, byte$,byte code

If you disable the LOCAL statement the effect will be to make the specified variables GLOBAL, which is highly undesirable. It's the sort of thing you can get away with in a small program, when you can remember what every variable is used for and where it is referenced, but in a large program it's a recipe for corrupting variables which are in use.

Incidentally the Disk Files section of the manual was not written by me, it was written by Doug Mounter even before BB4W existed, way back in the BBC BASIC (86) for MS-DOS days. So whilst the code (I hope) works, it is very dated and you may find something which is more to your liking on the Wiki:

http://bb4w.wikispaces.com/Database+and+Files

Richard.
Re: Working with strings
Post by CharlesB on Mar 7th, 2015, 12:37am

I am in deep here for this is all so new.

First, if I show you the example of "Writing to the End of a Serial Data File" in your help document, I get this

Below is WESTER1 in your help files and it produces an error.

rem F-WESER1
:
rem EXAMPLE OF WRITING TO THE END OF A SERIAL DATA FILE
:
rem This program opens a file and sets PTR to the end
rem before writing more data to it.
:
rem A function is used to open the file.
:
oscli "CD """+@usr$+""""
:
phonenos=fn_openend("PHONENOS.DAT")
print "File Name PHONENOS.DAT Opened as Channel "laughhonenos
print
repeat
input "Name ? " name$
if name$="" then proc_end
input "Phone Number ? " phone$
print
print#phonenos,name$,phone$
until false
:
def proc_end
close#phonenos
end
:
:
rem Open the file 'AT END'.
:
rem If the file does not already exist, it is created
rem with OPENOUT. PTR# is left at zero and the file
rem number is returned. If the file exists, PTR# is
rem set to the end and the file number returned.
:
def fn_openend(name$)
local fnum
fnum=openup(name$)
if fnum=0 then fnum=openout(name$): =fnum
ptr#fnum=ext#fnum
=fnum

as the program executes the "local fnum" line, just a few lines before the end, I get the error "No such FN/PROC"


****************************************************But, when I go to the examples program below, I get no error.
So, it was from this example program that I modified and produced a small program that handled my serial file quite well.
It was only when I moved it into my larger file that the very same line the "local fnum" line that I get a "syntax error."

Below is the online Example Program
rem F-WESER1
:
rem EXAMPLE OF WRITING TO THE END OF A SERIAL DATA FILE
:
rem This program opens a file and sets PTR to the end
rem before writing more data to it.
:
rem A function is used to open the file.
:
oscli "CD """+@usr$+""""
:
phonenos=fn_openend("PHONENOS.DAT")
print "File Name PHONENOS.DAT Opened as Channel "laughhonenos
print
repeat
input "Name ? " name$
if name$="" then proc_end
input "Phone Number ? " phone$
print
print#phonenos,name$,phone$
until false
:
def proc_end
close#phonenos
end
:
:
rem Open the file 'AT END'.
:
rem If the file does not already exist, it is created
rem with OPENOUT. PTR# is left at zero and the file
rem number is returned. If the file exists, PTR# is
rem set to the end and the file number returned.
:
def fn_openend(name$)
local fnum
fnum=openup(name$)
if fnum=0 then fnum=openout(name$): =fnum
ptr#fnum=ext#fnum
=fnum


As I mentioned, I am looking into the help files on "LOCAL" but this is quite difficult for me to understand as I do not understand the words that are used to define higher-level words. I'm still more-or-less at your tutorial level.

If it comes down to it, and you want me to send you the main program, I will -- but it really will be a mess to you. Also, I have put the data files into specific directories For example, (c:\busadafiles\priceincrease.dat) and I don't know if you would want copies of those files.


**********************
And I found another glitch.
In one of the Example files this code works.

def fn_read

local data$,byte$,byte
dat$=""
repeat
byte=bget#compat
if byte=&1A or eof#compat then close#compat: end
if not(byte=&0A or byte=&0D or byte=&2C) then data$=data$+chr$(byte)
until byte=&0D or byte=&2C
=data$

But, when put in my larger program, I get a syntax error on the line

local data$,byte$,byte

If I could put this in color, your syntax coloring colors "local data" as orange, but the "$" is in black.

Re: Working with strings
Post by rtr2 on Mar 7th, 2015, 09:10am

on Mar 7th, 2015, 12:37am, CharlesB wrote:
And I found another glitch...
But, when put in my larger program, I get a syntax error on the line
Code:
local data$,byte$,byte 

If I could put this in color, your syntax coloring colors "local data" as orange, but the "$" is in black.

That, at least, has a simple explanation. As I mentioned, the Disk Files section of the manual was written many moons ago, before BB4W ever existed and, crucially, before the Lowercase Keywords option was available.

Therefore the programs in that section may not be, and in this case definitely isn't, compatible with lowercase keywords. The reason is, of course, that DATA is a keyword so whilst the variable data$ is normally valid, it isn't when lowercase keywords are enabled.

The clue was staring you in the face, had you recognised it: the 'variable' was shown as data$ showing that data was recognised as a keyword.

BBC BASIC traditionally requires all keywords to be in capitals. I added the Lowercase Keywords option as a concession (BB4W is the only one of the many versions of BBC BASIC which supports it) but possible incompatibility with existing programs is one unfortunate consequence. Personally I only ever use CAPITAL keywords because that's what I'm used to, and it makes many more variable names available.

Richard.
Re: Working with strings
Post by CharlesB on Mar 7th, 2015, 2:27pm

on Mar 7th, 2015, 09:10am, g4bau wrote:
That, at least, has a simple explanation. As I mentioned, the Disk Files section of the manual was written many moons ago, before BB4W ever existed and, crucially, before the Lowercase Keywords option was available.

Therefore the programs in that section may not be, and in this case definitely isn't, compatible with lowercase keywords. The reason is, of course, that DATA is a keyword so whilst the variable data$ is normally valid, it isn't when lowercase keywords are enabled.

The clue was staring you in the face, had you recognised it: the 'variable' was shown as data$ showing that data was recognised as a keyword.

Richard.



So, I took off the lower case option and I got the same error and the same DATA$ coloring.

So, I assume that I should create some other variable name, like INFO_IN$ in place of DATA$?
Re: Working with strings
Post by rtr2 on Mar 7th, 2015, 2:52pm

on Mar 7th, 2015, 2:27pm, CharlesB wrote:
So, I took off the lower case option and I got the same error and the same DATA$ coloring.

To be expected: DATA is now in capitals so still a keyword!

When Lowercase Keywords is disabled, data$ (lowercase) is a valid variable name. DATA$ (capitals) is never valid.

This problem does not occur in any other BASIC dialect (as far as I know); it's unique to BBC BASIC. Although there were valid justifications for the behaviour in 1981 (it makes it possible to squeeze programs into significantly less memory), it's not really something I would want to defend in 2015.

Both QB2BBC and LBB (the QBasic to BBC BASIC and Liberty BASIC to BBC BASIC translators respectively) tackle the issue by prefixing 'problem' variable names with an underscore, so in this case it would be converted to _DATA$.

Richard.

Re: Working with strings
Post by KenDown on Mar 7th, 2015, 3:58pm

And the same will apply to the fnum error, as BASIC will read it as FNum!

I must admit that it seems slightly perverse for Charles to be writing his BASIC keywords in lower case and then writing his REMs all in upper case!

Follow the "best practice" rules and you will make life a great deal easier for yourself:
*All* BASIC keywords in upper case
*All* variable names in lower case
REMs in upper and lower as you would write any other text
Re: Working with strings
Post by rtr2 on Mar 7th, 2015, 4:14pm

on Mar 7th, 2015, 3:58pm, KenDown wrote:
And the same will apply to the fnum error, as BASIC will read it as FNum!

True, I hadn't considered that possibility. It may be worth noting that the Cross Reference Utility (slot 5 in the Utilities menu, usually) will warn you if you have any variables in your program that would be incompatible with Lowercase Keywords if that option was enabled.

Quote:
Follow the "best practice" rules... *All* variable names in lower case

I wouldn't consider that 'best practice', and again the Cross Reference Utility will complain if you do that. It assumes the variable naming conventions will be followed:
Richard.

Re: Working with strings
Post by CharlesB on Mar 7th, 2015, 9:29pm

on Mar 7th, 2015, 3:58pm, KenDown wrote:
And the same will apply to the fnum error, as BASIC will read it as FNum!

I must admit that it seems slightly perverse for Charles to be writing his BASIC keywords in lower case and then writing his REMs all in upper case!

Follow the "best practice" rules and you will make life a great deal easier for yourself:
*All* BASIC keywords in upper case
*All* variable names in lower case
REMs in upper and lower as you would write any other text


Thanks Ken, I appreciate the advice.