in reply to Re^3: string manipulation
in thread string manipulation


Last Question :-) I open file to read and should retrevie all the lines start with " SOURCE=.\" as display below:
SOURCE=.\ApplicationObject.cpp SOURCE=.\BusinessObject.cpp SOURCE=.\ClientObject.cpp SOURCE=.\ComponentServer.cpp SOURCE=.\main.cpp SOURCE=.\posix_timer.cpp SOURCE=.\ServiceServer.cpp SOURCE=.\SystemObject.cpp SOURCE=.\TestProgram.cpp SOURCE=.\workflow.cpp

I need to initialize variable only with the file name, so finally I should have:
$fileLst=" ApplicationObject.cpp BusinessObject.cpp ClientObject.cpp ComponentServer.cpp" My current code is:
foreach my $line (<MAKFILE>) { chomp $line; if ($line =~ m/SOURCE=\.\\(.*)$/i) { push @fileLst, $1; } } close MAKFILE; $fileLst = join " ", @fileLst; return $fileLst;

The final result includes garbage: "workflow.cppcppppppp".
Please advice. Thanks.

Replies are listed 'Best First'.
Re^5: string manipulation
by blazar (Canon) on May 18, 2008 at 15:31 UTC
    foreach my $line (<MAKFILE>) {

    I personally believe you should know that almost always in Perl (5) the Right™ way to iterate over the lines of a file is a while loop. You should also be using lexical filehandles.

    if ($line =~ m/SOURCE=\.\\(.*)$/i) {

    I generally chomp too, but incidentally $ matches right before \n too; you may also push the return value of the match operator.

    $fileLst = join " ", @fileLst;

    Perhaps you prefer to be explicit, and I'm sure many people would say that you're right, but there's a very convenient shortcut for join " ", @fileLst, which is "@fileLst"; also, I see no reason to create an intermediate temporary variable just to return it.

    All in all, I will give you an example subroutine which will accept a filename and give you your expected output:

    sub domkfile { my ($fname, @flist)=shift; open my $fh, '<', $fname or die "Can't open `$fname': $!\n"; push @flist, /SOURCE=\.\\(.*)$/i while <$fh>; "@flist"; }

    If slurping the whole file at once is not a problem, and indeed it should not be in this case, you may avoid the use of the @flist array with a map:

    sub domkfile { my $fname=shift; open my $fh, '<', $fname or die "Can't open `$fname': $!\n"; join ' ' => map /SOURCE=\.\\(.*)$/i, <$fh>; }
    --
    If you can't understand the incipit, then please check the IPB Campaign.