I'm writing a routine to parse a string based on field delimiters. This is part of my HL7 parser which I'm converting to EB from another BASIC language.
As you can see in the debug output below, the variable wvar3 is being truncated ... I think the for-next loop is failing but don't see how.
In the code block below you will see the initialization section, the parsesegment subroutine (with DEBUG statements) and the output from the debug run. Any pointers/hints/ideas are greatly appreciated.
Thanks in advance.
window w ' Main window
dialog d1 ' Help screen
dialog d2 ' About screen
CONST nrents = 50
DEF myfile : FILE
DEF filter : string
DEF ary[100],lbls[100],mtype[nrents,2],x1,x2,tstring : string
DEF segvals[200,2] : string
DEF wvar1[25000], wvar2[25000], wvar3[25000] : istring
DEF mainsep$ : char
DEF secsep$ : char
GLOBAL mainsep$
GLOBAL secsep$
GLOBAL nrlines
GLOBAL lbls
GLOBAL ary
GLOBAL nrfound
GLOBAL numlines
GLOBAL wvar1
GLOBAL wvar2
GLOBAL wvar3
SUB parsesegment
DEF ndx : INT
DEF i : INT
DEF s$ : STRING
$IFDEF DEBUG
DEBUGPRINT "Entering wvar3 = " + wvar3
DEBUGPRINT "Len of wvar3 = " + str$(len(wvar3))
$ENDIF
for i=1 to 200
segvals[i,1] = ""
segvals[i,2] = ""
next i
ndx = 1
s$ = ""
for i=1 to len(wvar3)
if mid$(wvar3,i,1) <> mainsep$
s$ = s$ + mid$(wvar3,i,1)
$IFDEF DEBUG
DEBUGPRINT "s$ = " + s$
DEBUGPRINT "wvar3 = " + wvar3
DEBUGPRINT "i = " + str$(i)
$ENDIF
else
segvals[ndx,2] = s$
$IFDEF DEBUG
DEBUGPRINT "segvals[ndx,2] = " + segvals[ndx,2]
$ENDIF
ndx = ndx + 1
s$ = ""
endif
next i
segvals[ndx,2] = s$
nrfound = ndx
$IFDEF DEBUG
DEBUGPRINT "Exiting wvar3 = " + wvar3
DEBUGPRINT "Len of wvar3 = " + str$(len(wvar3))
DEBUGPRINT "s$ = " + s$
$ENDIF
STOP
ENDSUB
Starting debug session...
Loading DLL: ntdll.dll
Loading DLL: C:\WINDOWS\system32\kernel32.dll
Loading DLL: C:\WINDOWS\system32\USER32.DLL
Loading DLL: C:\WINDOWS\system32\GDI32.dll
Loading DLL: C:\WINDOWS\system32\COMDLG32.DLL
Loading DLL: C:\WINDOWS\system32\SHLWAPI.dll
Loading DLL: C:\WINDOWS\system32\ADVAPI32.dll
Loading DLL: C:\WINDOWS\system32\RPCRT4.dll
Loading DLL: C:\WINDOWS\system32\msvcrt.dll
Loading DLL: C:\WINDOWS\system32\COMCTL32.dll
Loading DLL: C:\WINDOWS\system32\SHELL32.dll
Loading DLL: C:\WINDOWS\system32\OLE32.DLL
Loading DLL: C:\WINDOWS\system32\CRTDLL.DLL
Loading DLL: C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b641W
Loading DLL: C:\WINDOWS\system32\uxtheme.dll
Loading DLL: C:\WINDOWS\system32\riched32.dll
Loading DLL: C:\WINDOWS\system32\RICHED20.dll
Line cleanup ends
Sorting completed
Entering parsesegment
wvar3 = MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3
Entering wvar3 = MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3
Len of wvar3 = 70
Exiting wvar3 =
Len of wvar3 = 0
s$ =
User breakpoint encountered: Address 0x00412C64
The program 'C:\EBasicWork\parserv4.exe' exited with code: 1
Tom
I have since added
GLOBAL segvals
and am now also getting an access violation error in the debug output.
Also, forgot to tell you (probably obvious) that mainsep$ is the vertical bar ( | ) character.
Tnx.
Tom
One more thing and then I promise to go away for a while ... ;)
I isolated the parse routine into a console .exe and it runs just fine - parses out the fields and displays them as I asked it to do.
Here's that code:
OPENCONSOLE
DEF i : INT
DEF s$ : STRING
DEF wvar3 : STRING
DEF mainsep$ : char
wvar3 = "MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3"
mainsep$ = "|"
s$ = ""
for i=1 to len(wvar3)
if mid$(wvar3,i,1) <> mainsep$
s$ = s$ + mid$(wvar3,i,1)
else
print s$
s$ = ""
endif
next i
print s$
print : print wvar3
DO:UNTIL INKEY$ <> ""
CLOSECONSOLE
and here's the output
MSH
^~\&
LAE
E
MCK
E
20080104000035
ORM^O01
Q117025049T94885091
D
2.3
MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3
Note that wvar3 isn't modified at all in this console version of the routine.
Tnx.
Tom
Look at all the places in your code where the variables "wvar3" and "mainsep$" are being used. Where are they being initialized relative to the routine you are processing them in?
It's almost like you haven't given "wvar3" or "mainsep$" a value before calling the routine.
I say that because if the len was 1 or more then and it found a "|" the value of "i" would be printed with debugprint.
put a debugprint right after the "for i" line is and see what the 2 variables are there.
Larry
Thanks, Larry.
I have a DEBUGPRINT right after my DEF statements in the subroutine and it shows the correct values for those variables but I'll put another one in right before the for-next loop just to be sure.
Appreciate the input!
Tom
Instead of using mid$(....)
You have the wvar3 defined as ISTRING, you could just do:
if wvar3[i] <> mainsep$
But you would have to start the index at 0.
Bill
Bill,
How would that work?
mainsep$ is always the char "|" that he is using as a separartor.
wvar3 is a istring that contains multiple "|" with data between them.
He has, as I see it , the choice of using a loop with the mid$ function to test each char at a time or
using a "while" and the instr function with a starting point to test for the "|" character.
But not just the testing of one variable against the separator as you have shown.
What am I missing?
tbohon.
seems like I remember having problems one time testing against a CHAR type variable.
If the debugprint suggestion I gave you shows the proper value "|" is there then just for me change mainsep$ to a string instead of a char and try again.
Larry
Bill,
I see you changed your typo while I was typing. I understand your correction fully.
Larry
Bill: Will give that a shot next.
Larry: No difference - if you match the DEBUGPRINT statements in the code below to the debug output (bottom of code block) it doesn't appear that the for-next loop is executing at all. Is the len() function valid for istrings??? If that were undefined or less than 1, the loop wouldn't execute. However, I also print the value of len(wvar3) which is 70 ... so it appears to be working.
Anyway, here's the code and the debug output. Only thing not included is the change of mainsep$ from char to string in the global definition.
Thanks guys.
SUB parsesegment
DEF ndx : INT
DEF i : INT
DEF s$ : STRING
$IFDEF DEBUG
DEBUGPRINT "Entering wvar3 = " + wvar3
DEBUGPRINT "Len of wvar3 = " + str$(len(wvar3))
$ENDIF
for i=1 to 200
segvals[i,1] = ""
segvals[i,2] = ""
next i
$IFDEF DEBUG
DEBUGPRINT "segvals cleared"
$ENDIF
ndx = 1
s$ = ""
$IFDEF DEBUG
DEBUGPRINT "Enter i-loop"
$ENDIF
for i=1 to len(wvar3)
$IFDEF DEBUG
DEBUGPRINT "In i-loop, wvar3 = " + wvar3
$ENDIF
if mid$(wvar3,i,1) <> mainsep$
s$ = s$ + mid$(wvar3,i,1)
$IFDEF DEBUG
DEBUGPRINT "s$ = " + s$
DEBUGPRINT "wvar3 = " + wvar3
DEBUGPRINT "i = " + str$(i)
$ENDIF
else
segvals[ndx,2] = s$
$IFDEF DEBUG
DEBUGPRINT "segvals[ndx,2] = " + segvals[ndx,2]
$ENDIF
ndx = ndx + 1
s$ = ""
endif
next i
segvals[ndx,2] = s$
nrfound = ndx
$IFDEF DEBUG
DEBUGPRINT "Exiting wvar3 = " + wvar3
DEBUGPRINT "Len of wvar3 = " + str$(len(wvar3))
DEBUGPRINT "s$ = " + s$
$ENDIF
STOP
ENDSUB
Starting debug session...
Loading DLL: ntdll.dll
Loading DLL: C:\WINDOWS\system32\kernel32.dll
Loading DLL: C:\WINDOWS\system32\USER32.DLL
Loading DLL: C:\WINDOWS\system32\GDI32.dll
Loading DLL: C:\WINDOWS\system32\COMDLG32.DLL
Loading DLL: C:\WINDOWS\system32\SHLWAPI.dll
Loading DLL: C:\WINDOWS\system32\ADVAPI32.dll
Loading DLL: C:\WINDOWS\system32\RPCRT4.dll
Loading DLL: C:\WINDOWS\system32\msvcrt.dll
Loading DLL: C:\WINDOWS\system32\COMCTL32.dll
Loading DLL: C:\WINDOWS\system32\SHELL32.dll
Loading DLL: C:\WINDOWS\system32\OLE32.DLL
Loading DLL: C:\WINDOWS\system32\CRTDLL.DLL
Loading DLL: C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b641W
Loading DLL: C:\WINDOWS\system32\uxtheme.dll
Loading DLL: C:\WINDOWS\system32\riched32.dll
Loading DLL: C:\WINDOWS\system32\RICHED20.dll
Line cleanup ends
Sorting completed
Entering parsesegment
wvar3 = MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3
Entering wvar3 = MSH|^~\&|LAE|E|MCK|E|20080104000035||ORM^O01|Q117025049T94885091|D|2.3
Len of wvar3 = 70
segvals cleared
Enter i-loop
Exiting wvar3 =
Len of wvar3 = 0
s$ =
User breakpoint encountered: Address 0x00412CDA
The program 'C:\EBasicWork\parserv4.exe' exited with code: 1
All I can say is I don't know what else to suggest unless you give me the entire code so I can compile it on my machine.
Larry
You indexes are wrong. Arrays are zero based.
for i=1 to 200
segvals[i,1] = ""
segvals[i,2] = ""
next i
Should be:
for i=0 to 199
segvals[i,0] = ""
segvals[i,1] = ""
next i
Since you are specifying an index greater than the arrays capacity you are overwriting memory on the stack, specifically the variable you are having problems with.
A common method, one I don't particularly like, is to increased the size of your arrays by 1 so you can use the 1 to 200, instead of 0 to 199. I find that messy and wasteful though ;)
Paul.
Thanks, Paul. I'll make the mods in the morning when I'm at least partially awake.
Best,
Tom