Why is the output the way it is? -Splitting and chop

Anon Source

I'm trouble understanding the output of the below code. 1. Why is the output Jo Al Ch and Sa? Doesn't chop remove the last character of string and return that character, so shouldn't the output be n i n and y? 2. What is the purpose of the $firstline=0; line in the code? 3. What exactly is happening at the lines

foreach(@data) 
{$name,$age)=split(//,$_);
print "$name $age \n";     

The output of the following code is

Data in file is:

J o
A l
C h
S a

The file contents are:

NAME AGE
John 26
Ali 21
Chen 22
Sally 25

The code:

#!/usr/bin/perl
my ($firstline,
@data,
$data);

open (INFILE,"heading.txt") or die $.;

while (<INFILE>)
{
if ($firstline)
{
$firstline=0;
}
else
{
chop(@data=<INFILE>);
}
print "Data in file is: \n";
foreach (@data)
{
($name,$age)=split(//,$_);
print "$name $age\n";
}
}
perl

Answers

answered 6 months ago Dev123 #1

There are few issues with this script but first I will answer your points

  1. chop will remove the last character of a string and returns the character chopped. In your data file "heading.txt" every line might be ending with \n and hence chop will be removing \n. It is always recommended to use chomp instead. You can verify what is the last character of the line by running the command below:

    od -bc heading.txt
    
    0000000 116 101 115 105 040 101 107 105 012 112 157 150 156 040 062 066
              N   A   M   E       A   G   E  \n   J   o   h   n       2   6
    
    0000020 012 101 154 151 040 062 061 012 103 150 145 156 040 062 062 012
             \n   A   l   i       2   1  \n   C   h   e   n       2   2  \n
    
    0000040 123 141 154 154 171 040 062 065 012
              S   a   l   l   y       2   5  \n
    
    0000051
    

    You can see \n

  2. There is no use of $firstline because it is never been set to 1. So you can remove the if/else block.

  3. In the first line it is reading all the elements of array @data one by one. In 2nd line it is splitting the contents of the element in characters and capturing first 2 characters and assigning them to $name and $age variables and discarding the rest. In the last line we are printing those captured characters. IMO, in line 2 we should do split based on space to actual capture the name and age. So the final script should looks like:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my @data;  
    open (INFILE,"heading.txt") or die "Can't open heading.txt: $!";
    while (<INFILE>) {
        chomp(@data= <INFILE>);
    }
    close(INFILE);
    
    print "Data in file is: \n";
    foreach (@data) {
        my ($name,$age)=split(/ /,$_);
        print "$name $age\n";
    }
    

    Output:

    Data in file is:
    John 26
    Ali 21
    Chen 22
    Sally 25
    

comments powered by Disqus