tags:

views:

79

answers:

5

Eg:

$variable = "10000";
for($i=0; $i<3;$i++)
{
   $variable++;
   $file = $variable."."."txt";
   open output,'>$file' or die "Can't open the output file!"; 
}

This doesn't work. Please suggest a new way.

+5  A: 

use double quotes: ">$file". single quotes will not interpolate your variable.

$variable = "10000";
for($i=0; $i<3;$i++)
{
   $variable++;
   $file = $variable."."."txt";
   print "file: $file\n";
   open $output,">$file" or die "Can't open the output file!";
   close($output);
}
ghostdog74
A: 

Use a file handle:

my $file = "whatevernameyouwant";
open (MYFILE, ">>$file");
print MYFILE "Bob\n";
close (MYFILE);

print '$file' yields $file, whereas print "$file" yields whatevernameyouwant.

Anders Oestergaard Jensen
A: 

You almost have it right, but there are a couple of issues.

1 - You need to use double quotes around the file you're opening. open output,">$file" or die[...] 2 - Minor niggles, you don't close the files afterwards.

I'd rewrite your code something like this:

#!/usr/bin/perl
$variable = "1000";
for($i=0; $i<3;$i++) {
        $variable++;
        $file = $variable."."."txt";
        open output,">$file" or die "Can't open the output file!";
}
Arcterex
+2  A: 

The problem is that you're using single quotes for the second argument to open, and single-quoted strings do not interpolate variables mentioned in them. Perl interpreted your code as though you wanted to open a file that really had a dollar sign for the first character of its name. (Check your disk; you should see an empty file named $file there.)

You can avoid the issue by using the three-argument version of open:

open output, '>', $file

Then the file-name argument can't accidentally interfere with the open-mode argument, and there's no unnecessary variable interpolation or concatenation.

Rob Kennedy
+11  A: 

Everyone here has it right, you are using single quotes in your call to open. Single quotes do not interpolate variables into the quoted string. Double quotes do.

my $foo  = 'cat';

print 'Why does the dog chase the $foo?';  # prints: Why does the dog chase the $foo?
print "Why does the dog chase the $foo?";  # prints: Why does the dog chase the cat?

So far, so good. But, the others have neglected to give you some important advice about open.

The open function has evolved over the years, as has the way that Perl works with filehandles. In the old days, open was always called with the mode and the file name combined in the second argument. The first argument was always a global filehandle.

Experience showed that this was a bad idea. Combining the mode and the filename in one argument created security problems. Using global variables, well, is using global variables.

Since Perl 5.6.0 you can use a 3 argument form of open that is much more secure, and you can store your filehandle in a lexically scoped scalar.

open my $fh, '>', $file or die "Can't open $file - $!\n";
print $fh "Goes into the file\n";

There are many nice things about lexical filehandles, but one excellent property is that they are automatically closed when their refcount drops to 0 and they are destroyed. There is no need to explicitly close them.

Something else worth noting is that it is considered by most of the Perl community that it is a good idea to always use the strict and warnings pragmas. Using them helps catch many bugs early in the development process and can be a huge time saver.

use strict;
use warnings;

for my $base ( 10_001..10_003 ) {

   my $file = "$base.txt";
   print "file: $file\n";

   open my $fh,'>', $file or die "Can't open the output file: $!";

   # Do stuff with handle.
}

I simplified your code a bit too. I used the range operator to generate your base numbers for the file names. Since we are working with numbers and not strings, I was able to use the _, as the thousands separator to improve readability without impacting the final result. Finally, I used an idiomatic perl for loop instead of the C style for you had.

I hope you find this helpful.

daotoad