9

Why the following String comparison is not working? I have the following code (I adapted it to make is simpler). I retrieve a player from the database and add it to a list of players. Then I loop on the list of player and try to find it, and even tho' the string is the same, the comparison return false..

def findPlayer2(self, protocol, playerId):
    cur = self.conn.cursor()
    cur.execute("SELECT playerId, playerName, rating FROM players WHERE playerId LIKE (%s)", [playerId])
    nbResult = cur.rowcount
    result = cur.fetchone()
    cur.close()

    if nbResult > 0:
        player = Player(protocol, str(result[0]), str(result[1]), result[2])
        self.players.append(player)

    for player in self.players:
        id1 = str(player.playerId)
        id2 = str(playerId)
        print type(id1)
        print type(id2)
        print "Comparing '%s' with '%s'" % (id1, id2)

# HERE IS THE COMPARISON

        if id1 == id2:
            print "Equal! Player found!"
            return player
        else:
            print "Not equal :("

Give the following result:

<type 'str'>
<type 'str'>
Comparing '11111111' with '11111111'
Not equal :(
HLP
  • 2,142
  • 5
  • 19
  • 20
  • 13
    Use `%r` instead of `'%s'`. Perhaps some non-printable characters or lookalikes. –  Jun 05 '13 at 14:25
  • Seems like you are right, here's the new result: **Comparing ''11111111'' with ''11111111\x00''**. Do you know why this happen? – HLP Jun 05 '13 at 14:27
  • 1
    what was the type of playerID that was sent to the function? which python version? – Loïc Faure-Lacroix Jun 05 '13 at 14:32
  • As someone who uses Bash a lot my msitake was I put [ ] around the condition (facepalm emoji) as in if [ str =="[]" ] . Adding in case someone else needs this – SidJ Oct 01 '19 at 07:42

2 Answers2

8

You seem to have a string processing error. PlayerId seems to be a C-String being stored in a unicode String.

Background: C uses a nullbyte (\x00) to mark the end of a string. Since this nullbyte is in your string it ends up in the string representation of the object.

You can take a look here, for some reference. But without more code I am not sure about the cause/fix.

Have you tried type(playerId)?

edit: I don't know what python implementation you are using, for cpython look here

Unfortunately I am not to firm in interfacing c and python, however you could try to use PyString_FromString to convert it on the c side to a python string or use some handcrafted function (eg split with regex at the first unescaped 0).

Some interfacing libs are listed in this awnser

Community
  • 1
  • 1
ted
  • 4,791
  • 5
  • 38
  • 84
  • Right, actually the playerId is coming over the network from a C program. What would be the best way to remove that nullbyte terminator. – HLP Jun 05 '13 at 14:41
  • Actually I just removed the last char on the C side. Seems to work. Thanks! – HLP Jun 05 '13 at 14:53
  • Ok I was not sure if you have control over both sides, but as it turns out you do. Check out [`PyString_FromString`](http://docs.python.org/2/c-api/string.html) anyway. – ted Jun 05 '13 at 14:55
4

You can strip any non-printable characters like so

import string
player = ''.join(filter(lambda c: c in string.printable, player))
Niklas R
  • 16,299
  • 28
  • 108
  • 203