Android Question Bug? Error comparing two strings

makis_best

Active Member
Licensed User
Hi

I try to compare a string with the content of one EditText
But the code refuse to continuous inside If / End If
The result of the Log is correct as you can see below.
Why?

B4X:
Dim EmailTxt As EditText
Dim Local_Email As String
Log(EmailTxt.Text & " = " & Local_Email)
If EmailTxt.Text = Local_Email Then
    Wait For (CallSub(Me, "ChangePass")) Complete (Result As Boolean)
        ........
End If
 

José J. Aguilar

Well-Known Member
Licensed User
In the log you are just showing the string "siaka@gmail.com = siaka@gmail.com", not the boolean comparation.
Try in the log
B4X:
Log(EmailTxt.Text  =  & Local_Email)
It should show "True" or "False", right now probably "False" because the if sentence is not executing.
Make tesst in the log line until you get "True".
i.e. try to trim both variables, or convert to lowcase, etc...
 

emexes

Well-Known Member
Licensed User
Probably because Strings are objects, and when comparing objects, the "=" operator is comparing whether the two objects are actually the same one physical object in memory, not whether those objects have the same byte patterns. That's why the String class has a CompareTo method, that compares the actual byte patterns of the strings.

upload_2019-7-11_8-32-4.png


So in light of all that, try:
B4X:
Dim EmailTxt As EditText
Dim Local_Email As String
Log(EmailTxt.Text & " = " & Local_Email)
If Local_Email.CompareTo(EmailTxt.Text) = 0 Then
    Wait For (CallSub(Me, "ChangePass")) Complete (Result As Boolean)
        ........
End If
:)
 
Last edited:

makis_best

Active Member
Licensed User
Strange...

I try your solution but I use the same condition in several places in my code and work fine.
Why only in this condition?
 

agraham

Expert
Licensed User
Probably because Strings are objects... That's why the String class has a CompareTo method...
Not true I'm afraid. B4A translates string equality comparisons to (Local_Email).equals(EmailText.getText()) where 'equals' is the Java string content, not identity, comparison. String comparison in B4A using '=' has never failed for me so there is something else happening here. :(

As an aside, I have found it quite easy to change from Java to C# and back apart from this one case which used to trip me up all the time. C# overloads '=' for Strings to do a content comparison but Java does not support overloading so '=' on Strings remains an identity comparison so slipping into C# syntax for comparisons usually fails - to my constant bewilderment until the penny drops (yet again)!
 
Last edited:

makis_best

Active Member
Licensed User
[QUOTE="String comparison in B4A using '=' has never failed for me so there is something else happening here. :(
[/QUOTE]

So..... It is a bug?
 

emexes

Well-Known Member
Licensed User
Not true I'm afraid. B4A translates string equality comparisons to (Local_Email).equals(EmailText.getText()) where 'equals' is the Java string content, not identity, comparison.

Well, I'm thanking my lucky stars now that I prefaced my thinking with "Probably" :)

String comparison in B4A using '=' has never failed for me so there is something else happening here.
I am having trouble trying to reproduce the problem too. But the example presented seems simple enough, and the quoted log doesn't seem to have any spurious spaces about it, so... hmm.
 

makis_best

Active Member
Licensed User
It's certainly interesting.

Did using the .CompareTo method fix the problem where it was occurring in your app?
Yes...

With the .CompareTo working fine....
For test I remove it and I use again the = sing but the problem return.
 

udg

Expert
Licensed User
Two more tests you could try:
- substitute == to =
- log both strings' length
 

emexes

Well-Known Member
Licensed User
Try adding these two Log statements, using the "=" rather than .CompareTo, and post the result:
B4X:
Log(EmailTxt.Text & " = " & Local_Email)
Log(EmailTxt.Text.Length & " " & Local_Email.Length)    '''add this
If EmailTxt.Text = Local_Email Then
    Log("Bazinga!")    '''add this
    Wait For (CallSub(Me, "ChangePass")) Complete (Result As Boolean)
 
Last edited:

DonManfred

Expert
Licensed User
Dim EmailTxt As EditText
Dim Local_Email As String
Log(EmailTxt.Text & " = " & Local_Email)
If EmailTxt.Text = Local_Email Then
Wait For (CallSub(Me, "ChangePass")) Complete (Result As Boolean)
........

End If
Local_Email is never set to any value. How should a compare work here?
 

emexes

Well-Known Member
Licensed User
With the .CompareTo working fine....
For test I remove it and I use again the = sign but the problem return.
Hmm. I've been trying to reproduce the problem here, but can't. I am using B4A 9.00 - are you on the same version?

How do you feel about trimming out private stuff from your project, confirming that the problem still occurs, and then posting the project's File, Export As Zip archive?
 

makis_best

Active Member
Licensed User
Hmm. I've been trying to reproduce the problem here, but can't. I am using B4A 9.00 - are you on the same version?

How do you feel about trimming out private stuff from your project, confirming that the problem still occurs, and then posting the project's File, Export As Zip archive?
My version is 9.00

Here it is the code of the Activity

B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private EmailTxt As EditText
    Private PasswordTxt As EditText
    Private LoginBtn As Button
    Dim Curs1 As Cursor
    Dim SQlScript As String
    Dim Local_Email, Local_Password As String
    Dim Local_PASSWORDCHANGED As Int
    Dim Ime1 As IME
    
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Activity.LoadLayout("Login.bal")
    Ime1.Initialize("")
    Ime1.SetCustomFilter (EmailTxt, EmailTxt.INPUT_TYPE_TEXT, "abcdefghijklmnopqrstuvwxyz1234567890.@-_")
    Ime1.AddHeightChangedEvent
    SQlScript = "Select * from LOCAL_Settings"
    Starter.LocalSQL.Initialize(File.DirRootExternal & "/DroidViewDB/", "DVDatabase.db", True)
    Curs1 = Starter.LocalSQL.ExecQuery(SQlScript)
    For i = 0 To Curs1.RowCount - 1
        Curs1.Position = i
        Local_Email = Curs1.GetString("EMAIL")
        Local_Password = Curs1.GetString("PASSWORD")
        Local_PASSWORDCHANGED = Curs1.GetInt("PASSWORDCHANGED")
    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub LoginBtn_Click
    Log(Local_Email.CompareTo(EmailTxt.Text))                  Result      ----->    siaka@gmail.com = siaka@gmail.com
    Log(EmailTxt.Text.Length & " " & Local_Email.Length)    Result      ----->    80 80
    If Local_Email.CompareTo(EmailTxt.Text) = 0 Then
        Wait For (CallSub(Me, "ChangePass")) Complete (Result As Boolean)
        If Result Then
            Activity.Finish
        Else
            ToastMessageShow("Η αλλάγή του κωδικού δεν ολοκληρώθηκε.", True)
        End If
    Else
        ToastMessageShow("Το Email δεν είναι σωστό.", True)
    End If
End Sub

Sub ChangePass As ResumableSub
    Return True
End Sub
 

emexes

Well-Known Member
Licensed User
Things are still not working the way we would expect, but my two current best hypotheses are:

- Something to do with SQL or something treating strings as null-terminated, perhaps adding an ASCII 0x00 into the string, and other parts of Java or B4A "helpfully" hiding or ignoring this by treating the null as the end of the string, rather than crashing with error or continuing on into probable junk characters

- Something to do with strings that *look* the same not actually being the same: perhaps some character-set encoding/translation has resulted in different unicode characters being used for what should be the same character
 
Top