Announcement

Collapse
No announcement yet.

ASCIIZ UDT Array Scan

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
    Michael Mattias
    Member

  • Michael Mattias
    replied
    > ... I figured that it was the limitation of strings ending at the first chr$(0).

    It's not a 'limitation' or even a 'feature' of ASCIIZ strings at all; your problem is caused by the misuse of FROM..TO in your ARRAY SCAN code. You told the compiler to compare the valid portion of the string with the entire buffer length. Lo and behold, that's exactly what it did.

    As my late sainted mother might have said, "Be careful what you ask for, you just might get it."

    MCM

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    Ian,
    If string can be used instead of asciiz
    then you could do it this way...

    Code:
    #COMPILE EXE '#Win 8.04#
    #DIM ALL
    #INCLUDE "WIN32API.INC" '#2005-01-27#
     
    TYPE sType
      First  AS STRING * %MAX_PATH
      Second AS STRING * %MAX_PATH
    END TYPE
    '______________________________________________________________________________
     
    FUNCTION PBMAIN () AS LONG
     LOCAL ItemCount AS LONG
     LOCAL Index     AS LONG
     LOCAL Retval1   AS LONG
     LOCAL Retval2   AS LONG
     LOCAL sTry      AS STRING * %MAX_PATH
     
     DIM sArray(0 TO 500) AS STRING * %MAX_PATH
     DIM sTypeArray(0 TO 500) AS sType
     
     sArray(0) = "A" : sTypeArray(0).First = "A" : sTypeArray(0).Second = "A"
     sArray(1) = "A" : sTypeArray(1).First = "A" : sTypeArray(1).Second = "A"
     sArray(2) = "A" : sTypeArray(2).First = "A" : sTypeArray(2).Second = "A"
     sArray(3) = "A" : sTypeArray(3).First = "A" : sTypeArray(3).Second = "A"
     sArray(4) = "B" : sTypeArray(4).First = "A" : sTypeArray(4).Second = "B"
     sArray(5) = "C" : sTypeArray(5).First = "A" : sTypeArray(5).Second = "C"
     sArray(6) = "D" : sTypeArray(6).First = "A" : sTypeArray(6).Second = "D"
     
     ItemCount = 6
     Index = 1
     sTry = "A"
     
     'First scan is position within ASCIIZ standard array - this works properly
     ARRAY SCAN sArray(Index) FOR ItemCount, <> sTry, TO Retval1
     
     ARRAY SCAN sTypeArray(Index) FOR ItemCount, FROM %MAX_PATH + 1 TO %MAX_PATH * 2, <> sTry, TO Retval2
     
     MSGBOX "Return values should be item 4, the first non-match"   & $CRLF & _
            "Standard string array search returns:" & STR$(Retval1) & $CRLF & _
            "String UDT search returns:"            & STR$(Retval2)
     
     
    END FUNCTION
    '______________________________________________________________________________
    '
    Pierre Bellisle
    Member
    Last edited by Pierre Bellisle; 27 Jan 2008, 06:28 PM.

    Leave a comment:

  • Michael Mattias
    Member

  • Michael Mattias
    replied
    What are you doing? Eliminating duplicates from a list?

    Here's a couple of demos I did which kind of do that in two different ways:

    Count unique keys and occurrences thereof in sequential file

    Win32: Find Differences in WIN32API.INC and other text files April 21, 2000

    Don't go by the thread titles....that's just the way I have my list saved. Both demos contain various forms of "eliminate duplicates from a list."

    MCM

    Leave a comment:

  • Ian Cairns
    Member

  • Ian Cairns
    replied
    Pierre, yes you could do that for the simple example, but not for a more complex UDT with several fields.

    Michael, Yes, I figured that it was the limitation of strings ending at the first chr$(0). And this is one of the "workarounds" I had in mind to do the comparison on only a subset that might be valid. I was just hoping against hope that a feature request might be added to ARRAY SCAN to allow for scanning for ASCIIZ structures.

    Thanks for both of your inputs.

    regards, Ian

    Leave a comment:

  • Michael Mattias
    Member

  • Michael Mattias
    replied
    Your FROM..TO is forcing a comparison of the enitre SIZEOF the member , but your ASCIIZ data are only valid up to the first CHR$(0). Therefore you are comparing strings of different lengths, which never will be equal.

    When you don't specify the FROM..TO, the compiler is smart enough to know where the valid data are.

    If you want to compare only part of the string, you need to make your FROM..TO correspond to the valid length of the seach target.

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    Ian,
    reading the help, seem's you could do...

    Code:
      DIM Temp(0 TO 6) AS ASCIZ * %MAX_PATH AT VARPTR(AzTest2(0))
      ARRAY SCAN Temp(ndx) FOR noItems, <> azString, TO retVal2

    Leave a comment:

  • Ian Cairns
    Member

  • Ian Cairns
    started a topic ASCIIZ UDT Array Scan

    ASCIIZ UDT Array Scan

    You can sort UDT arrays by member using their position. You can SCAN them the same way, unless the item is an ASCIIZ member.

    The attached program illustrates my problem. I am looking for the first non-match in a UDT array (which contains more members than the example here, of course). I can SCAN and match a standard ASCIIZ array, but not a UDT array containing an ASCIIZ member. I am not indicating there is anything "wrong" with the tools provided by the wonderful PB team, probably it is just the blockhead using them.

    So, am I doing something wrong? Or can you just "not get there from here?" I know how to work around this problem, but I want to know if it can be done with the fine tools produced by Bob's group.

    Regards, Ian Cairns.
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "c:\basic\pbwin8\winapi\win32api.inc"
    
    TYPE AzTestTYPE
      xFirst AS ASCIIZ * %MAX_PATH
    END TYPE
    
    '------------------------
    '########################
    '------------------------
    FUNCTION PBMAIN () AS LONG
      DIM noItems AS LONG, _
          ndx      AS LONG, _
          sp1      AS LONG, _
          sp2      AS LONG, _
          retVal1  AS LONG, _
          retVal2  AS LONG, _
          azString AS ASCIIZ * %MAX_PATH
    
      DIM AzTest(0:500)  AS LOCAL ASCIIZ * %MAX_PATH
      DIM AzTest2(0:500) AS LOCAL AzTestTYPE
    
      noItems = 6
      AzTest(1) = "C:\temp" : AzTest2(1).xFirst = AzTest(1)
      AzTest(2) = "C:\temp" : AzTest2(2).xFirst = AzTest(2)
      AzTest(3) = "C:\temp" : AzTest2(3).xFirst = AzTest(3)
      AzTest(4) = "F:\temp" : AzTest2(4).xFirst = AzTest(4)
      AzTest(5) = "D:\temp" : AzTest2(5).xFirst = AzTest(5)
      AzTest(6) = "X:\temp" : AzTest2(6).xFirst = AzTest(6)
    
    ' Get position of xFirst member within UDT
      sp1 = VARPTR(AzTest2(1).xFirst) - VARPTR(AzTest2(1)) +1
      sp2 = sp1 + SIZEOF(AzTest2(1).xFirst)-1
      ndx = 1
    
    ' value to scan for - want first non-match.
      azString = AzTest2(ndx).xFirst
    
    ' First scan is position within ASCIIZ standard array - this works properly
      ARRAY SCAN AzTest(ndx) FOR noItems, <> azString, TO retVal1
      
    ' Second scan is position within ASCIIZ UDT array
      ARRAY SCAN AzTest2(ndx) FOR noItems, FROM sp1 TO sp2, <> azString, TO retVal2
    ' This returns incorrect results also:
    '  ARRAY SCAN AzTest2(ndx) FOR noItems, <> azString, TO retVal2
    
      MSGBOX "Return values should be item 4, the first non-match" + $CR _
             + "Standard ASCIIZ array search returns: " + FORMAT$(retVal1) + $CR _
             + "ASCIIZ UDT search returns: " + FORMAT$(retVal2)
    
    
    END FUNCTION
    '------------------------
    '########################
    '------------------------
Working...
X