ArrayTools

Array manipulation Tools by Mark Rodgers

Module Notes

The code is fully commented and is written to allow me to understand how to work with arrays of data.

The first tool is designed to use a known string of data and search an array for its occurence and return the position in the array of the character immediately following the last character of the search string.

I am using this to parse an array of data from a Telit GE863-GPS MODEM in order to find the position of the NMEA data following the echoed command sent to the MODEM.

All details of use and operation and enclosed along with a working example and the results obtained with real hardware!

The module contains DEBUG lines that send information via the Hardware Serial port, these can all be removed or commented out if not required, the DEBUG lines are very clearly marked with the comment "'DEBUG OUTPUT", none of these lines are required to make the module work.

I hope to add tools as I develop them in the near future.

The Array Manipulation Module Code

{
*****************************************************************************
*  Name    : Array_Tools.bas                                                *
*  Author  : Mark Rodgers                                                   *
*  Notice  : Copyright (c) 2007 Mark Rodgers                                *
*          : All Rights Reserved                                            *
*  Date    : 19/09/2007                                                     *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
'******************************************************************************

'******************************************************************************
    Module Array_Tools

'******************************************************************************

'******************************************************************************
    Include "string.bas"
    Include "usart.bas"'only required for DEBUG OUTPUT
    Include "convert.bas"'only required for DEBUG OUTPUT

'******************************************************************************

'******************************************************************************

'HOW "Public Function FIND_STRING" IS USED:-
'##############################################################################
    'FIND_STRING(string_to_find As String,ByRef array_to_test() As Char,start_of_file As Word,end_of_file As Word) As Word
    '"string_to_find" IS THE STRING YOU ARE LOOKING FOR IN YOUR DATA ARRAY,
    'CURRENTLY THE MAXIMUM LENGTH IS AS THE COMPILERS DEFAULT OF 23 CHARACTERS.
    '
    '"array_to_test()" IS THE ARRAY OF DATA YOU HAVE CREATED, NO RESTRICTION IS
    'PLACED ON THE MAXIMUM SIZE ABOVE THOSE OF THE COMPILER.
    '
    '"start_of_file" IS THE STARTING POINT IN THE ARRAY THAT YOU WISH TO BEGIN
    'THE SEARCH, MUST BE NO MORE THAN "end_of_file" MINUS "string_to_find_length".
    '
    '"end_of_file" IS THE LENGTH OF THE FILE WITHIN THE ARRAY, UP TO THE FULL
    'SIZE OF THE ARRAY, THIS IS NOT AN EXPLCIT VALUE AS THE START MUST BE, BUT
    'IS THE VALUE OF THE LENGTH OF THE KNOWN FILE INSIDE THE ARRAY.
    '
    'EXAMPLE:-
    '##################################
    'Include "usart.bas"
    'Include "convert.bas"
    'include "Array_Tools.bas"
    '
    'Dim test_array(100) as Char                    'our test array
    'Dim temp_index as byte                         'used in array initialization
    '
    'position in array immediately after last character in our search string
    'Dim next_character_position as byte
    '
    ''INITIALISE THE ARRAY, STARTING AT 1
    '##################################
    'temp_index=0
    'While temp_index<Bound(test_array)
        'test_array(temp_index)=temp_index+1
        'Inc(temp_index)
    'Wend
    '##################################
    '
    'While1=1
    '   next_character_position=FIND_STRING("12345",test_array,0,Bound(test_array))
    '  
    '   USART.SetBaudrate(br9600)'DEBUG OUTPUT
    '   USART.Write("next_character_position=",DecToStr(next_character_position),13)'DEBUG OUTPUT
    '   USART.Write("next_character=",test_array(next_character_position),13,13)'DEBUG OUTPUT
    '   
    '   DelayMS(1000)
    'Wend
    '##################################
    '
    'THIS PROGRAM PRODUCES THIS OUTPUT ON A TERMINAL:-
    '
    'Start Position=0
    'string_to_find=12345
    'String Length=5
    'start character found=1
    'start position=48
    'compare string created=12345
    'next_character_position=53
    'next_character=6
    '
    'THE POSITION FOR THE FIRST CHARACTER MAY SEEM STRANGE BUT AS THE ARRAY IS
    'OF "Char" TYPE IS WILL LOOK AT THE ASCII VALUES PRINTED ON A TERMONAL SCREEN
    'AND NOT THEIR DECIMAL VALUE, THEREFORE 1 ("1") IS DECIMAL 49 AND IS LOCATED
    'AT POSITION 48 IN THE ARRAY.
'##############################################################################


'HOW "Public Function FIND_STRING" WORKS:-
'##############################################################################
    'USE THE "char_to_find" TO SEARCH THE ARRAY FOR THE FIRST OCCURENCE
    'OF THIS REFERENCE CHARACTER, ONCE FOUND A "temp_string" IS GENERATED
    'OF "string_to_find_length", THAT IS COMPARED WITH "string_to_find",
    'IF THEY ARE EQUAL THE VALUE OF "loop" IS GIVEN TO "result" AND RETURNED
    'TO THE CALLING ROUTINE.
    '
    'IF THE "temp_string" IS NOT EQUAL TO "string_to_find" THE "char_to_find"
    'IS SEARCHED FOR AGAIN, AND IF FOUND RE-TESTED AS ABOVE.
    '
    'IF NOTHING IS FOUND THAT COMPARES TO "string_to_find", THE "result"
    'IS GIVEN A VALUE OF 0 TO INDICATE THE ROUTINE FAILED.
    '
    'THE ROUTINE WILL FAIL IF THE "string_to_find" DOES NOT HAVE 2 OR MORE
    'CHARACTERS, "result" WILL BE 0 EVEN IF "string_to_find" HAS ONE CHARACTER.
    '
    'THE ROUTINE WILL ALSO FAIL IF THE START ADDRESS IS LARGER THAN THE END
    'ADDRESS, OR IF THERE IS NOT ENOUGH ROOM FROM THE START ADDRESS TO READ THE
    'REQUIRED CHARACTERS IN "string_to_find".
'##############################################################################

Public Function FIND_STRING(string_to_find As String,ByRef array_to_test() As Char,start_of_file As Word,end_of_file As Word) As Word
    Dim loop As Word                                'print loop counter
    Dim array_loop As Word                          'array find loop counter
    Dim temp_index As Word                          'index for "temp_string"
    Dim temp_loop As Word                           'temporary loop value
    Dim temp_string As String                       'holds the string to compare to the one we wish to find
    Dim char_to_find As Char                        'the character to look for
    Dim temp_char As Char                           'temporary character storage
    Dim string_to_find_length As Byte               'holds the length of the string

    loop=start_of_file                              'start at "start_of_file" position
    array_loop=0                                    'start at zero
    temp_loop=0                                     'initialize
    char_to_find=string_to_find(0)                  'initial character to find
    temp_char=255                                   'initialise
    string_to_find_length=Length(string_to_find)    'the length of the string we are looking for

    'when returned a value of zero indicates the string was not found
    '(any good string must have more than zero characters)
    result=0                                        


USART.SetBaudrate(br9600)
USART.Write("Start Position=",DecToStr(loop),13)'DEBUG OUTPUT
USART.Write("string_to_find=",string_to_find,13)'DEBUG OUTPUT
USART.Write("String Length=",DecToStr(string_to_find_length),13)'DEBUG OUTPUT


    'THE ROUTINE MUST HAVE AT LEAST 2
    'CHARACTERS, IF NOT "result"=0.
    '##################################
    'there must be at least 2 characters in the string
    If string_to_find_length<2 Then                 
USART.Write("NOT ENOUGH CHARACTERS",13)'DEBUG OUTPUT
        result=0                                    'indicate the routine has failed
        Exit                                        'exit the routine
    EndIf
    '##################################


    'TEST FOR CORRECT START AND END
    'OF FILE VALUES.
    '##################################
    'the start of file must be less than the end of file
    If start_of_file<end_of_file Then               

        'the start point must allow the full string length to be read
        If end_of_file<start_of_file+string_to_find_length Then
USART.Write("START VALUE TOO HIGH, NO ROOM FOR READ",13)'DEBUG OUTPUT            
            result=0                                'indicate the routine has failed            
            Exit                                    'exit the routine
        EndIf

        Else                                        'start of file is greater than end of file
USART.Write("START VALUE HIGHER THAN END VALUE",13)'DEBUG OUTPUT
        result=0                                    'indicate the routine has failed
        Exit                                        'exit the routine

    EndIf
    '##################################


    'BEGIN THE SEARCH.
    '##################################
find_start:    
    'look for the position in the array of the occurence of the character to find
    While temp_char<>char_to_find And loop<end_of_file
        temp_char=array_to_test(loop)               'test this position in the array
        Inc(loop)                                   'move to next position
    Wend

    'test validity of data, loop is currently at required start character
    'plus 1 due To "Inc(loop)" in While-Wend routine above
    If temp_char=array_to_test(loop-1) Then             
        Dec(loop)                                   'move back one position
USART.Write("start character found=",array_to_test(loop),13)'DEBUG OUTPUT
USART.Write("start position=",DecToStr(loop),13)'DEBUG OUTPUT            

        'only test if there are enough characters left
        If loop<end_of_file-string_to_find_length Then
            temp_index=0                            'ensure this counter starts at zero
            temp_loop=loop                          'remember current position

            'check a maximum of "string_to_find_length" characters
            While loop<temp_loop+string_to_find_length
                temp_string(temp_index)=array_to_test(loop)'create the temporary string
                Inc(loop)                           'look at the next charater
                Inc(temp_index)                     'next character in "temp_string"    
            Wend

USART.Write("compare string created=",temp_string,13)'DEBUG OUTPUT
DelayMS (100)'DEBUG OUTPUT    

            'the strings are equal and the index can now be found
            If temp_string=string_to_find Then      

                'the returned value is the index in the array of the character
                'immediately following the last one in the "string_to_find"
                result=loop                       

                Else
USART.Write("string not found",13)'DEBUG OUTPUT        

                'the "string_to_find was not found so keep checking until the end of the file
                GoTo find_start                     
            EndIf
        EndIf

        Else
USART.Write("next start character not found",13)'DEBUG OUTPUT
    EndIf
    '##################################

End Function

'******************************************************************************

'******************************************************************************

A demostration program showing the results on a terminal.

{
*****************************************************************************
*  Name    : Test_FIND_STRING.bas                                           *
*  Author  : Mark Rodgers                                                   *
*  Notice  : Copyright (c) 2007 Mark Rodgers                                *
*          : All Rights Reserved                                            *
*  Date    : 19/09/2007                                                     *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
'******************************************************************************

'******************************************************************************
Program Test_FIND_STRING

'******************************************************************************

'******************************************************************************
    Include "usart.bas"                             'ONLY USED IN DEBUG OUTPUT
    Include "convert.bas"                           'ONLY USED IN DEBUG OUTPUT
    Include "Array_Tools.bas"                       'contains "FIND_STRING" function

'******************************************************************************

'******************************************************************************
    Dim test_array(100) As Char                    'our test array
    Dim temp_index As Byte                         'used in array initialization
    Dim next_character_position As Byte            'the position in the array immediately after the last character in our search string

'******************************************************************************

'******************************************************************************
'INITIALISE THE ARRAY, STARTING AT
'1(DECIMAL).
'##################################
temp_index=0
While temp_index<Bound(test_array)
    test_array(temp_index)=temp_index+1
    Inc(temp_index)
Wend
'##################################



'SEARCH FOR A STRING OF CHARACTERS
'IN AN ARRAY AND RETURN THE POSITION
'OF THE CHARACTER IMMEDIATELY AFTER
'THE LAST CHARACTER IN THE SEARCH STRING.
'
'THE DATA PRODUCED IN THE TERMINAL:-
'
'Start Position=0
'string_to_find=12345
'String Length=5
'start character found=1
'start position=48
'compare string created=12345
'next_character_position=53
'next_character=6
'##################################
While 1=1
   next_character_position=FIND_STRING("12345",test_array,0,Bound(test_array))

   USART.SetBaudrate(br9600)'DEBUG OUTPUT
   USART.Write("next_character_position=",DecToStr(next_character_position),13)'DEBUG OUTPUT
   USART.Write("next_character=",test_array(next_character_position),13,13)'DEBUG OUTPUT
    DelayMS(1000)
Wend
'##################################

'******************************************************************************

'******************************************************************************