Question about struct.unpack

E

Eric Jacoboni

Hi,

To experiment with unpacking, i've written a little C code which
stores one record in a file. Then, i try to reread this file to unpack
the record.

Here's the struct of a record:

typedef struct {
char nom[30];
double taille;
int age;
char plop;
} enreg_t;

The whole size, as given by sizeof() is 48, due to byte alignment.

I was first thinking that "32sdic" would make the job, but calcsize()
reports only 45 for this format. So, without knowing what, i've tried
"32sdicxxx" to reach the 48 expected... Now it works...

The same file, re-read with a Ruby script needs a
str.unpack("Z32dIc").

So, i don't know why i need to pad the format string in Python. Any
clue?

BTW: how to get rid of all this stuff after the \0 in the first field
in Python? (Ruby has Z and A, but it seems that the Python 's'
specifier is like 'A' and there is no 'Z' equivalent)
 
S

Scott David Daniels

Eric said:
Hi,

To experiment with unpacking, i've written a little C code which
stores one record in a file. Then, i try to reread this file to unpack
the record.

Here's the struct of a record:

typedef struct {
char nom[30];
double taille;
int age;
char plop;
} enreg_t;

The whole size, as given by sizeof() is 48, due to byte alignment.
...i've tried "32sdicxxx" to reach the 48 expected... Now it works...

The same file, re-read with a Ruby script needs a
str.unpack("Z32dIc").

So, i don't know why i need to pad the format string in Python. Any
clue?

BTW: how to get rid of all this stuff after the \0 in the first field
in Python? (Ruby has Z and A, but it seems that the Python 's'
specifier is like 'A' and there is no 'Z' equivalent)

OK, the correct translation of your format is: '30sdic' (size 45) or
'30sdic3x' if you are passing the entire 48-char block. The reason
it is not size 48 is that '30sdicc' (size 46) in C takes no more room.
the alignment to the end shows up in a C sizeof.

data = struct.pack('30sdic', 'John Q. Public', 57123.25, 43, 'M')
nomz, taille, age, plop = struct.unpack('30sdic', data)
nom = nomz.rstrip('\0')



--Scott David Daniels
(e-mail address removed)
 
E

Eric Jacoboni

Thanks for your explanations.

But :
nom = nomz.rstrip('\0')

doesn't work for me:
'Dupont\x00\x80\xbf\xff\xf70\x8f\xe0u\xa4\x00\x00.8\xfe\xfe\xfe\xff\x80\x80\x80\x80'
'Dupont\x00\x80\xbf\xff\xf70\x8f\xe0u\xa4\x00\x00.8\xfe\xfe\xfe\xff\x80\x80\x80\x80'
 
S

Scott David Daniels

Eric said:
But :

doesn't work for me:

'Dupont\x00\x80\xbf\xff\xf70\x8f\xe0u\xa4\x00\x00.8\xfe\xfe\xfe\xff\x80\x80\x80\x80'

Sorry, I thought you had NUL-filled data.
For NUL terminated data:
nom = nomz[: nomz.index('\0')]

--Scott David Daniels
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top