Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses


by mbayer (Novice)
on Nov 22, 2005 at 20:18 UTC ( [id://510887] : perlquestion . print w/replies, xml ) Need Help??

mbayer has asked for the wisdom of the Perl Monks concerning the following question:

I am attemting to open a file read its contents in and directly write them to another file. But when try to open a nother file it just shuts out???
$output_file = ""; $input_file = "mikels.out"; $quit_code = "quit\n"; open(FILE, $input_file); #opens data.txt in read-mode open(FILE, ">$output_file"); #opens file to be written to while(<FILE>){ #reads line by line from chomp; print "Saw $_ in data.txt\n"; print FILEHANDLE $_; #print the output file con +tents } close $input_file; #close the file. #close $output_file; #close the file.

Replies are listed 'Best First'.
by Roy Johnson (Monsignor) on Nov 22, 2005 at 20:27 UTC
    You can't use the same file handle for two different files at the same time. It's madness, I tell you! Madness!

    Caution: Contents may have been coded under pressure.

      Thanks for making me laugh out loud! I needed that.

      Update: Please note, I'm not disagreeing with Roy Johnson's comment. The way it is written made me laugh...that's all.

by jonadab (Parson) on Nov 22, 2005 at 20:28 UTC

    In cases like this, you can get more detailed error messages by printing $! if certain builtin functions (like open or close) return false. Also, you probably want two different filehandles, since you're wanting to use both at the same time.

    update: Oh, and close takes a filehandle for its argument.
    Try something along these lines:

    $output_file = ""; $input_file = "mikels.out"; $quit_code = "quit\n"; open(INFILE, $input_file) or die "Cannot read from input file: $!"; open(OUTFILE, ">$output_file") or die "Cannot write to output file: $! +"; while(<INFILE>){ chomp; print "Saw $_ in data.txt\n"; print FILEHANDLE $_ or warn "Can't print: $!"; } close INFILE or die "Can't close INFILE: $!\n"; close OUTFILE or die "Can't close OUTFILE: $!\n";

    I believe I left (at least) one error in the code, but because of the added sanity checks, you'll now probably find it right away, as soon as you run the thing.

      print FILEHANDLE $_ or warn "Can't print: $!";
      should be
      print OUTFILE $_ or warn "Can't print: $!";

      Also, it's kinda silly to keep looping after print returns an error, since you bothered to check the return value.

      I guess you can see I haven't done much with Perl >:) -- Thanks for the info, didn't know you can change FILEHANDLES like that? Wonder what else I can change? Hhhmmmmm..... Thanks again. The Syntax kills me every time.
by larryp (Deacon) on Nov 22, 2005 at 20:43 UTC

    Hi mbayer,

    Inserting use strict; and use warnings; at the beginning of your script would help you isolate and fix some of the problems. For example, this would've helped you notice that the file handle FILEHANDLE was used only once.

    Including those statements is a good idea in general, because they will help to point out problems that might come up later.



by aufflick (Deacon) on Nov 23, 2005 at 00:58 UTC
    The error is pointed out above, but I would like to suggest that you use lexical variables instead of magic file handles. In perl 5.6 or later, instead of using barewords like FILE you can use variables like this:

    use strict; my $output_file_name = ""; my $input_file_name = "mikels.out"; my $output_file_handle; my $input_file_handle; open( $input_file_handle, $input_file_name) or die "Unable to open input file '$input_file_name' : $!"; open( $output_file_handle, $output_file_name) or die "Unable to open output file '$output_file_name' : $!"; while (<$input_file_handle>) { do_stuff; } close $input_file; close $output_file;
    IMHO this is a much cleaner way to handle file handles. It also often protects you from leaving file handles lying around. If the code above was in a sub definition (or any other block like an if () {}) the file handles would automatically be closed by perl as soon as the variables fell out of scope at the end of the block - even if you forgot to call close.