Prev: help with big numbers and DBI
Next: FAQ 4.8 How do I perform an operation on a series of integers?
From: freesoft12 on 9 Feb 2010 14:16 Hi, I have a written a C++ program that writes a set of paths into a binary file. In the program, the 'write_binary()', writes to the binary file and the 'read_binary()' opens the binary file, reads the data and prints it out. Here is the C++ program: ----------------------------- #include <vector> #include <string> #include <stdio.h> using namespace std; void write_binary() { vector<string> v; v.push_back("/a/b/c/d"); v.push_back("/e/f"); v.push_back("../h"); FILE *fp = fopen("rw_binary.dat","w"); if (!fp) { printf("Error: Unable to open ./rw_binary.dat\n"); exit(1); } for (vector<string>::const_iterator it(v.begin()),itEnd(v.end());it!=itEnd;++it) { unsigned size = it->size()+1; fwrite(&size,sizeof(unsigned),1,fp); fwrite(it->c_str(),sizeof(char),size,fp); } fclose(fp); } void read_binary() { FILE *fp = fopen("rw_binary.dat","r"); while (!feof(fp)) { unsigned size(0); fread(&size,sizeof(unsigned),1,fp); char *buf = (char*)malloc(size*sizeof(char)); fread(buf,sizeof(char),size,fp); printf("%s\n",buf); free(buf); } fclose(fp); } int main() { write_binary(); read_binary(); return 0; } ---------------------- I wanted to create a Perl program that mimics the 'read_binary()'. But I am getting a perl warning ( I have the 'use strict & diagnostics'). Here it is: ----------------------- eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec perl -w -S $0 $argv:q' if 0; # use strict; use diagnostics; open(IN,"/home/rradhakr/progs/rw_binary.dat") or die "Cannot open rw_binary.dat\n"; binmode(IN); while (<IN>) { my $buf = 0; read(IN,$buf,6); my $string = undef; read(IN,$string,$size); print "$size\n"; } close(IN); ------------------------- Here is the error I get Perl: Argument "" isn't numeric in read at read_binary_file.pl line 13, <IN> line 1 (#1) (W numeric) The indicated string was fed as an argument to an operator that expected a numeric value instead. If you're fortunate the message will identify which operator was so unfortunate. Any suggestions? Regards John
From: Peter J. Holzer on 9 Feb 2010 14:37 On 2010-02-09 19:16, freesoft12(a)gmail.com <freesoft12(a)gmail.com> wrote: > unsigned size = it->size()+1; > fwrite(&size,sizeof(unsigned),1,fp); So this writes sizeof(unsigned) bytes containing the (implementation defined) binary representation of an unsigned int. You will need to check your compiler documentation for the details and be aware that they can change when you use a different compiler (or the same compiler using different flags). > fwrite(it->c_str(),sizeof(char),size,fp); This writes the string including the terminating "\0". > while (<IN>) { Here you read one line (i.e. everything up to including the first "\n" byte). Why? > my $buf = 0; > read(IN,$buf,6); ^ Where does the number 6 come from? You are obviously trying to read the unsigned int written by the C++ compiler. While it is theoretically possible that your unsigned ints are 6 bytes long, that would be extremely unusual. Most likely they are 4 bytes long (but 2 or 8 are also possible). > my $string = undef; > read(IN,$string,$size); Where does $size come from? You read the size into $buf, not into $size. Plus, the $buf will contain the size in the format specific to your C++ compiler, so you need to unpack() (see perldoc -f unpack) it before you can use it. > print "$size\n"; Why do you print $size instead of the $string? > } > close(IN); hp
From: Peter J. Holzer on 9 Feb 2010 14:42 On 2010-02-09 19:16, freesoft12(a)gmail.com <freesoft12(a)gmail.com> wrote: > I wanted to create a Perl program that mimics the 'read_binary()'. But > I am getting a perl warning ( I have the 'use strict & diagnostics'). > > Here it is: > > ----------------------- > eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec > perl -w -S $0 $argv:q' if 0; > # > > use strict; > use diagnostics; > > open(IN,"/home/rradhakr/progs/rw_binary.dat") or die "Cannot open > rw_binary.dat\n"; > binmode(IN); > while (<IN>) { > my $buf = 0; > read(IN,$buf,6); > my $string = undef; > read(IN,$string,$size); > print "$size\n"; > } > close(IN); > ------------------------- > > Here is the error I get Perl: > > Argument "" isn't numeric in read at read_binary_file.pl line 13, <IN> > line 1 (#1) Just noticed this now. This is impossible. Your program cannot even start since you forgot to declare $size. You were obviously running a different program than the one you posted. Please don't do that. hp
From: Peter Makholm on 9 Feb 2010 14:46 "freesoft12(a)gmail.com" <freesoft12(a)gmail.com> writes: > I wanted to create a Perl program that mimics the 'read_binary()'. But > I am getting a perl warning ( I have the 'use strict & diagnostics'). Are you sure that you pasted the right code? Neither $string nor $size is declared and I'm sure that 'use strict' would complain about this before the erroryou have pasted? > ----------------------- > eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec > perl -w -S $0 $argv:q' if 0; > # > > use strict; > use diagnostics; > > open(IN,"/home/rradhakr/progs/rw_binary.dat") or die "Cannot open > rw_binary.dat\n"; A matter of style, but use a lexical filehandle and the three-argument form of open. Incluing $! in the error message will also be usefull some time in the future: open my $fh, '<', '/home/rradhakr/progs/rw_binary.dat' or die "Couldn't open rw_binary.dat: $!"; As a consequence all occurences of IN should be replaced by $fh. > binmode(IN); > while (<IN>) { Here you read one line from the file including the line separator ("\n"). > my $buf = 0; Why? $buf is unconditionally overwritten by the next statement > read(IN,$buf,6); Here you read the following 6 bytes into $buf. > my $string = undef; This "initialization" is even worse. You never have to do an explicite initialization to undef. And then again, $string will be unconditionally overwritten by the following read. > read(IN,$string,$size); Here you read the following $size bytes into $string. BUT you havn't showed us where $size is declared, much less where it gets it's value from. If you code uses 'use strict' you clearly havn't pasted you complete code. But my guess is that this is line 13 and you somehow never initializes $size with an correct value. > print "$size\n"; > } > close(IN); Mixing reading files with the <> operator and with read() is confusing at best (and at least calls for a comment in you code) and plain wrong most of time. My guess is that your case is the latter //Makholm
From: freesoft12 on 9 Feb 2010 20:10 Sorry about that, I posted the Perl program that I was playing with. Here is the orig Perl program: while (<IN>) { my $size = 0; read(IN,$size,1); my $string = undef; read(IN,$string,$size); print "$string\n"; } close(IN);
|
Next
|
Last
Pages: 1 2 Prev: help with big numbers and DBI Next: FAQ 4.8 How do I perform an operation on a series of integers? |