Comment struct décomp un c terminé chaîne nulle?

J’ai utilisé TCP pour envoyer des données au serveur Python. Les données sont comme:

struct protocol { unsigned char prot; int id; char name[32]; } 

Regardez le champ du name , il s’agit d’une chaîne dont la taille est terminée par un caractère NULL et dont la taille maximale est 32. Maintenant, j’utilise strcpy .

 protocol p; memset(&p, 0, sizeof(p)); strcpy(name, "abc"); 

Maintenant, je le décompresse en python.

 prot,id,name = struct.unpack("@Bi32s") 

Maintenant, le len(name) est 32. Mais il me faut la chaîne "abc" lorsque la longueur est 3.

Comment puis je faire ça?

Après le déballage, vous pouvez simplement faire un:

 name = name.split('\0', 1)[0] 

Sinon, vous pouvez utiliser le module ctypes :

 name = ctypes.create_ssortingng_buffer(name).value 

Il suffit d’obtenir la sous-chaîne jusqu’au premier \0 :

 prot,id,name = struct.unpack("@Bi32s") name= name[:name.index("\0")] 

Cela a la particularité de vérifier et d’échouer ( ValueError ) si \0 n’apparaît pas dans la chaîne.

Partitionnez-le avec un caractère nul ( '\0' ) après le décompactage:

 >>> prot, id, name = struct.unpack('@Bi32s', b'\0\0\0\0\0\0\0\0abc' + b'\0' * 29) >>> name, _, _ = name.partition('\0') >>> name 'abc' 

Alternative utilisant des ctypes :

 >>> from ctypes import * >>> >>> class Protocol(Structure): ... _fields_ = [("prot", c_char), ... ("id", c_int), ... ('name', c_char * 32)] ... >>> # sock.recv_into(buf) in real program ... buf = create_ssortingng_buffer(b'\0\0\0\0\0\0\0\0abc' + b'\0' * 29) >>> p = cast(buf, POINTER(Protocol)) >>> p[0].name 'abc' 

Pourquoi ne pas utiliser rssortingp pour enlever le rembourrage?

 prot,id,name = struct.unpack("@Bi32s") name = name.rssortingp(b'\0') 

Cela vous permettra également d’utiliser les 32 octets pour stocker le nom sans terminateur zéro. Cependant, cela implique que TOUS les octets de remplissage soient définis sur zéro.