File access sub works but for some reason with errors

mistermentality

Active Member
Licensed User
Longtime User
I have a sub to read a text file and search it for a specific piece of text so that it will match any search term found (test, test2, test3 or test4). The idea is that if test is found then the line of text following it will be displayed, the same for test2 and so on.

However if no match is found it gives an error about a Null pointer exception for this line of the sub....

If line.CompareTo(searchterm) = 0 Then found = True

Yet I get the same error if I type in the word test, the first keyword and first line of the text file. In other words if no match is found, or if I search for the first item in the text file I get this error and don't know why. Any ideas, please?

The test file is a plain text file that just contains what is within the quote marks below (not the quotes themselves):

"test
data for test
test2
data for test2
test3
yes its test3
test4
yes it is test4"

And the sub that searches is:
B4X:
Sub dosearch
   Reader.Initialize(File.OpenInput(File.DirAssets, "test.txt"))
    line = Reader.ReadLine
   found = False
    Do While line <> Null
        line = Reader.ReadLine
      If line.CompareTo(searchterm) = 0 Then found = True
      If found = True Then Exit
    Loop
   If found = False Then Msgbox("Didn't find ingredient", "Error:")
   If Found = True Then
   ingredient = line
   line = Reader.ReadLine
   description = line
   Reader.Close
   Msgbox(ingredient,description)
   End If
   End Sub

Where ingredient, description and line are strings and searchterm is a string that holds the text to find a match for, previously entered by the user.

I know that I can make this work if I read the file in as a list, so if I cannot find the answer I can adapt my code, but I would rather know why this code will never find the first line of text and why it crashes if no data is matched so I can learn from my apparent mistake so any advice is appreciated

Dave
 

kickaha

Well-Known Member
Licensed User
Longtime User
1) You are reading the first line, then reading the second line without checking the first
2) You are doing operations on a null line

Try this rearranged code
B4X:
Sub dosearch
   Reader.Initialize(File.OpenInput(File.DirAssets, "test.txt"))
    line = Reader.ReadLine
   found = False
    Do While line <> Null
              If line.CompareTo(searchterm) = 0 Then found = True
      If found = True Then Exit
                          line = Reader.ReadLine
    Loop
   If found = False Then Msgbox("Didn't find ingredient", "Error:")
   If Found = True Then
   ingredient = line
   line = Reader.ReadLine
   description = line
   Reader.Close
   Msgbox(ingredient,description)
   End If
   End Sub

I have moved "line = Reader.ReadLine" down the loop to correct your two issues

Was typing this cross posted with Erel - at least we agree
 
Upvote 0

mistermentality

Active Member
Licensed User
Longtime User
I was just about to reply and post that I just realised my error, can't believe that I didn't notice that. Why is it I only realised once I posted and embarrassed myself :signOops:

Thank you for the speedy answer. I changed the code to
B4X:
Sub dosearch
ingredient = searchterm
   Reader.Initialize(File.OpenInput(File.DirAssets, "test.txt"))
   found = False
    Do While line <> Null
        line = Reader.ReadLine
   If line <> Null AND line.CompareTo(searchterm) = 0 Then found = True
   If found = True Then Exit
    Loop
   If found = True Then description = Reader.ReadLine
   If found = False Then Msgbox("Didn't find ingredient", "Error:")
   Reader.Close
   End Sub

But it has made me think and I was wondering is there a way to trap file access errors so that, say an app was accessing user entered data in a file and it was not as expected, the error would not produce an error message.

I'm thinking of something like
On File Error
<do something>
End File Error

Dave
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
Dave,

Your new version works as long as you are sure line is not NULL before you enter the loop.

The version Erel and I outlined is the more elegant solution.
 
Upvote 0

mistermentality

Active Member
Licensed User
Longtime User
Sorry to be a pain, just trying to learn here but surely the new code I wrote does the same as the recommended code? If the first line turns out to be null wouldn't the following code simply exit the loop and leave found = False rather than produce an error?

B4X:
Sub dosearch
ingredient = searchterm
   Reader.Initialize(File.OpenInput(File.DirAssets, "test.txt"))
   found = False
    Do While line <> Null
        line = Reader.ReadLine
   If line <> Null AND line.CompareTo(searchterm) = 0 Then found = True
   If found = True Then Exit
    Loop
   If found = True Then description = Reader.ReadLine
   If found = False Then Msgbox("Didn't find ingredient", "Error:")
   Reader.Close
   End Sub

Dave
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
The way it differs is that it does not read a line before the loop, therefore the first loop test (and result) will be done on whatever the variable "line" contains, and this will not be part of the file you are testing.

Also if lines happens to be NULL, then the loop would not be run.

I would code your routine:
B4X:
Sub dosearch
    ingredient = searchterm
    Reader.Initialize(File.OpenInput(File.DirAssets, "test.txt"))
    found = False
    line = Reader.ReadLine
    Do While line <> Null
        If line.CompareTo(searchterm) = 0 Then 
            found = True
            Exit
        End If
        line = Reader.ReadLine
    Loop

    If found  Then 
        description = Reader.ReadLine
    Else
        Msgbox("Didn't find ingredient", "Error:")
    End If
    Reader.Close
End Sub

To minimise testing and improve the flow.
 
Last edited:
Upvote 0

mistermentality

Active Member
Licensed User
Longtime User

I see what you mean now, I was thinking my code would run the loop even were the content Null and then act accordingly if it found out that it was indeed Null so I stand corrected and have adjusted my code.

Thank you for being patient and explaining

Dave
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…