Announcement

Collapse
No announcement yet.

Scan String Array

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Scan String Array

    I'm having trouble with ARRAY SCAN.

    I've created a string array, and I'm trying to find the array element that contains the character string "Date:"

    This seems like such a basic thing, I'm embarrassed to post, but I've studied the manual and searched the message board... so here goes.

    I'm using vers 9.01.

    Here's my code:

    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
    
        DIM infile AS STRING
    
        DIM reg_date AS STRING
    
        DIM source_txt AS STRING
    
        DIM line_count AS LONG
        DIM arr_index&
    
        source_txt = ""
        source_txt = INPUTBOX$("Enter fully justified source TXT filename","Source file?")
        IF source_txt = "" THEN
            EXIT FUNCTION
        END IF
    
        OPEN source_txt FOR INPUT AS #1  'i.e. open message previously saved as text
        IF ERR THEN
            MSGBOX "Could not open source file",,"Unable to open file"
            EXIT FUNCTION
        END IF
    
        'get line count
        FILESCAN #1, RECORDS TO line_count
    
        'now read the lines of the message into an array
        DIM msgline(1 TO line_count) AS STRING
        LINE INPUT #1, msgline$() TO line_count  'populate the array
        CLOSE #1  'close source message text file
     
        'reg_date
        ARRAY SCAN msgline(), ="Date:", TO arr_index&  'find line containing the string date:
        MSGBOX "array index: " + STR$(arr_index)  'returns 0
        
        EXIT FUNCTION
    
    
    END FUNCTION
    The array is populated by reading a simple text file. Here's a sample:

    Code:
    MessageEarthLink.net | My Start Page | myVoice | My Account | Support |
    
                Message
                ‹ Previous | Next › | « Back to INBOX 
                   Forward... inline text as attachment     Move to... Trash  More 
                  Actions... View Headers View Source --------------- Mark Unread 
                  Flag Message 
                From: 
                To: 
                Subject: 
                Date: Apr 23, 2009 6:10 PM
                ‹ Previous | Next › | « Back to INBOX 
    
    
    © 2008 EarthLink, Inc. All Rights Reserved.
    Members and visitors to the EarthLink Web site agree to abide by our Policies 
    and Agreements
    EarthLink Privacy Policy 
    Web Mail version 6.0.32
    When my code is run the arr_index that is returned is zero.

    What am I doing wrong?

    Thanks.

    -- tom

  • #2
    Perhaps a typo:
    Code:
     MSGBOX "array index: " + STR$(arr_index)
    should read
    Code:
     MSGBOX "array index: " + STR$(arr_index&)
    Rod
    In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

    Comment


    • #3
      Rod, thanks, but no joy. The Array Scan statement is returning zero. It can't find the search string, even after I correct the typo you mention.

      -- tom

      Comment


      • #4
        Code:
        ARRAY SCAN msgline(), ="Date:", TO arr_index&  'find line containing the string
        This statement does not find an element containing the string, it finds an element which equals the string.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Thanks, Michael.

          The language in the help file that confused me says that this statement scans all or part of an array for a given value. I misconstrued what this means.

          Since I'm searching for a substring within a string array I suppose I'll need to loop through the elements of the array using INSTR() to see if the search string is found within any of them. This will suffice for my needs, but I'm curious. Might there be a better way?

          Thanks again.

          -- tom

          Comment


          • #6
            I think that's what you need to do, the trusty loop function:
            Code:
            FUNCTION ArrayContains(arr() AS STRING, findString AS STRING) AS LONG
               LOCAL ii AS LONG
               
               FOR ii = LBOUND(arr()) TO UBOUND(arr())
                  IF INSTR(arr(ii), findString) THEN
                     FUNCTION = ii
                     EXIT FUNCTION
                  END IF
               NEXT
            END FUNCTION
            then your code might check for the return:
            Code:
                findLine = ArrayContains(msgline(), "Date:")
                IF findLine THEN ? "Found at line" & STR$(findLine)

            Comment


            • #7
              Might there be a better way?
              I did a quick TIX check on the loop function's speed and it's about 15 tix per array byte. A 2GHz machine will check ~ 133 MB/sec--quite speedy.

              Comment


              • #8
                Thanks!

                Comment


                • #9
                  Looking at the supplied code and data and if you reread what Micheal posted you will see that the following, at least as I read it.

                  Code:
                  LINE INPUT #1, msgline$() TO line_count
                  will put into some element a line thus:
                  Code:
                  Date: Apr 23, 2009 6:10 PM     'this is what the array scan finds, not DATE:
                  which means there will be no line in the msgline$() that matches the string in the ARRAY SCAN statement:
                  Code:
                  ARRAY SCAN msgline(), ="Date:", TO arr_index&
                  which takes you to this line from the help on ARRAY SCAN:

                  If none of the scanned elements satisfy expression, zero will be stored in lvar&
                  which is exactly the result you're getting.

                  You might get what you want faster by doing:
                  Code:
                      FOR xx=1 TO line_count
                        IF LEFT$(msgline$(xx),5)="Date:" THEN arr_index& = xx
                      NEXT xx
                  Mr Gleason's code does the same thing in a different manner, but now you should know why you were getting the result you were getting.
                  Last edited by Rodney Hicks; 24 Apr 2009, 09:29 PM. Reason: to edit
                  Rod
                  In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                  Comment


                  • #10
                    Thanks, Rod. I appreciate the further explanation and example. The documentation is plain enough. I'm surprised I didn't understand it sooner. I suppose I was going too fast, and having hit the problem failed to slow down and actually read the material carefully. Jumped to the conclusion that my implementation of the function was flawed. Lesson learned (at least for a while). Thanks again.

                    -- tom

                    Comment


                    • #11
                      ???
                      Code:
                      ARRAY SCAN stringarray([start] [FOR COUNT] , _ 
                              =|>[=]|<[=]]| LIKE {stringvar|stringliteral} [COLLATE UCASE] TO IHit
                      ?????

                      MCM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        When scanning a string array, all characters of each element of the array are normally considered when performing comparisons. To limit the comparison to a specific subset of characters, use FROM to specify the start position, and TO to specify the end position that ARRAY SCAN will consider within each array element...
                        If the character positions always hold true to your sample data you could search with..
                        Code:
                        ARRAY SCAN msgline(), From 13 to 17, Collate UCASE, ="DATE:", TO arr_index&  'find line containing the string date:
                        Rgds, Dave

                        Comment


                        • #13
                          You could also concatanate the entire array into a single string with JOIN$ then just use one INSTR. If found then you would only have to add up the string lengths of the array members + 1 for the delimeter until you reach the found number so giving you the array member

                          Comment


                          • #14
                            found then you would only have to add up the string lengths of the array members + 1 for the delimeter until you reach the found number so giving you the array member
                            You wouldn't even have to get all those individual LEN() results if you've created a master string using JOIN$......

                            Once you get a hit with INSTR, just count the number of delimiters found in that JOINed string up to the point of the hit....
                            Code:
                            LOCAL pb AS BYTE PTR , bdelim AS BYTE 
                            
                               S = (JOINED string using delimiter) 
                               bDelim = ASC(delimiter) 
                               z = INSTR (target, s) 
                               pb  = STRPTR(s) 
                               IF Z then 
                                   ichar  = 0 
                                   DO UNTIL ichar = Z  
                                        IF @pb[ichar] = bDelim then
                                           INCR  element_no 
                                        END IF 
                                        INCR  iChar 
                                  LOOP 
                             END IF
                            (Something like that anyway).
                            ... because the number of delimiters found in the JOINed string *is* an "element counter."

                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Good point, I have no idea which would be faster, adding the the longs that are stored in every string desciptor or as you have shown a good use of pointers

                              Comment

                              Working...
                              X