Reputation: 107
As the title says, I have a program or better two functions to read and write a file either in an array or to one. But now to the mean reason why I write this: when running my test several times my test program that tests my functions produces more and more white space. Is there somebody that could explain my fail and correct me?
my code
Helper.pm:
#!/usr/bin/env perl
package KconfCtl::Helper;
sub file_to_array($) {
my $file = shift();
my ( $filestream, $string );
my @rray;
open( $filestream, $file ) or die("cant open $file: $!");
@rray = <$filestream>;
close($filestream);
return @rray;
}
sub array_to_file($$;$) {
my @rray = @{ shift() };
my $file = shift();
my $mode = shift();
$mode='>' if not $mode;
my $filestream;
if ( not defined $file ) {
$filestream = STDOUT;
}
else {
open( $filestream, $mode, $file ) or die("cant open $file: $!");
}
my $l = @rray; print $l,"\n";
foreach my $line (@rray) {
print $filestream "$line\n";
}
close($filestream);
}
1;
test_helper.pl:
use KconfCtl::Helper;
use strict;
my @t;
@t= KconfCtl::Helper::file_to_array("kconf.test");
#print @t;
my $t_index=@t;
@t[$t_index]="n";
KconfCtl::Helper::array_to_file(\@t, "kconf.test", ">");
the result after the first:
n
and the 2nd run:
n
n
Upvotes: 1
Views: 153
Reputation: 126742
When you read from a file, the data includes the newline characters at the end of each line. You're not stripping those off, but you are adding an additional newline when you output your data again. That means your file is gaining additional blank lines each time you read and write it
Also, you must always use strict
and use warnings 'all'
at the top of every Perl script; you should avoid using subroutine prototypes; and you should declare all of your variables as late as possible
Here's a more idiomatic version of your module code which removes the newlines on input using chomp
. Note that you don't need the #!
line on the module file as it won't be run from the command line, but you my want it on the program file. It's also more normal to export symbols from a module using the Exporter
module so that you don't have to qualify the subroutine names by prefixing them with the full package name
use strict;
use warnings 'all';
package KconfCtl::Helper;
sub file_to_array {
my ($file) = @_;
open my $fh, '<', $file or die qq{Can't open "$file" for input: $!}; #'
chomp(my @array = <$fh>);
return @array;
}
sub array_to_file {
my ($array, $file, $mode) = @_;
$mode //= '>';
my $fh;
if ( $file ) {
open $fh, $mode, $file or die qq{Can't open "$file" for output: $!}; #'
}
else {
$fh = \*STDOUT;
}
print $fh $_, "\n" for @$array;
}
1;
and your test program would be like this
#!/usr/bin/env perl
use strict;
use warnings 'all';
use KconfCtl::Helper;
use constant FILE => 'kconf.test';
my @t = KconfCtl::Helper::file_to_array(FILE);
push @t, 'n';
KconfCtl::Helper::array_to_file(\@t, FILE);
Upvotes: 5
Reputation: 12097
When you read in from your file, you need to chomp() the lines, or else the \n
at the end of the line is included.
Try this and you'll see what's happening:
use Data::Dumper; ## add this line
sub file_to_array($) {
my $file = shift();
my ( $filestream, $string );
my @rray;
open( $filestream, '<', $file ) or die("cant open $file: $!");
@rray = <$filestream>;
close($filestream);
print Dumper( \@rray ); ### add this line
return @rray;
}
you can add
foreach(@rray){
chomp();
}
into your module to stop this happening.
Upvotes: 3