in reply to Re: Read structure in Perl
in thread Read structure in Perl

I have written the records in the file using following way.
#include <stdio.h> #include <string.h> #include <malloc.h> #define DSZ 108 struct stud { char name[100]; int roll_no; }; struct student { struct stud s; int grade; }value; int main() { FILE *fps; struct student *buffer=(struct student*)malloc(sizeof(struct s +tudent)); int n,j; fps=fopen("Myfile","wb+"); value.s.roll_no=149; value.grade=1; strcpy(value.s.name,"myname"); n=fwrite(&value,DSZ,1,fps); rewind(fps); n=fread(buffer,DSZ,1,fps); printf("Name:%s Grade:%d NO:%d\n",buffer->s.name,buffer->grade +,buffer->s.roll_no); fclose(fps); }

Replies are listed 'Best First'.
Re^3: Read structure in Perl
by BrowserUk (Patriarch) on Mar 22, 2010 at 12:17 UTC

    Try this. '<:raw' is roughly equivalent to binmode. The unpack templates: 'A100' tells it to treat the first 100 bytes as a null terminated string; 'i'(*) means treat the next 4 bytes as a signed integer.

    #! perl -slw use strict; open IN, '<:raw', $ARGV[ 0 ] or die $!; my $binary = do{ local $/; <IN> }; ## read the whole file close IN; my( $name, $roll_no, $grade ) = unpack 'A100 i i', $binary; print "name: $name; no:$roll_no; grade:$grade"; __END__ C:\test>junk58 Myfile name: myname; no:149; grade:1
    (*If the data is read on a different hardware platform from that where it is written you may need to change the 'i' template.)

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks for your information.
Re^3: Read structure in Perl
by syphilis (Archbishop) on Mar 22, 2010 at 13:35 UTC
    Another alternative is to use Inline::C. This reads 'Myfile' correctly for me:
    use warnings; use Inline C => <<'EOC'; #define DSZ 108 struct stud { char name[100]; int roll_no; }; struct student { struct stud s; int grade; }value; void foo(char * fn) { FILE *fps; int n; struct student *buffer=(struct student*)malloc(sizeof(struct stud +ent)); fps=fopen(fn,"rb"); n=fread(buffer,DSZ,1,fps); printf("Name:%s Grade:%d NO:%d\n",buffer->s.name,buffer->grade,bu +ffer->s.roll_no); fclose(fps); } EOC foo("Myfile"); # outputs: # Name:myname Grade:1 NO:149
    It's trivial to return the values to perl, if need be (rather than simply print them to stdout). And if it's necessary to use perl's IO abstraction interface (see perldoc perlapio) instead of the usual C functions, then I think that could be accommodated, too.

    Cheers,
    Rob