May 22, 2024, 09:32:38 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Parsing Problem

Started by tbohon, January 04, 2008, 11:01:02 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

tbohon

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
"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)

tbohon

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
"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)

tbohon

January 04, 2008, 11:43:33 AM #2 Last Edit: January 04, 2008, 11:56:00 AM by tbohon
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
"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)

LarryMc

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
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

tbohon

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
"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)

billhsln

January 04, 2008, 03:01:26 PM #5 Last Edit: January 04, 2008, 03:04:58 PM by billhsln
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
When all else fails, get a bigger hammer.

LarryMc

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
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Bill,
I see you changed your typo while I was typing. I understand your correction fully.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

tbohon

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

"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)

LarryMc

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
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

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.
Ionic Wind Support Team

tbohon

Thanks, Paul.  I'll make the mods in the morning when I'm at least partially awake.

Best,

Tom
"If you lead your life the right way, the karma will take care of itself ... the dreams will come to you."  -- Randy Pausch, PhD (1961-2008)