in reply to Help Me!

I personally would not consider this a particularly good first assignment in Perl. So, in this case I don't mind giving some extra help.

Yes, you started out in a good way!! You do not need to "declare $_", it just always exists as the loop iterator unless you over-ride it which you did as with my $word. Perl has a number of magic variables like that. I put a comment in the code if I'm using an obscure one. I view $_ as Perl's variable and very seldom assign directly to it myself. I view it as good practice to use a variable like 'my $word' because it often adds value to the loop in terms of documentation. Here, $word is not much help but 'my $IP_address', 'my $customer' might mean more in other situations.

If you split on something other than the default regex which is /\s+/, you need to take into account what happens to the newline and the end of the input line. The Perl function chomp() removes that and works on Windows as well as Unix. Otherwise the '\n' winds up at the end of the last thing in the split().

The implementation question before you is: "how to get the right tag words in front of the right thing from the line".

The input line has a fixed order to it. In many languages like C++, you would be thinking along the lines of using an indexed array of strings with this fixed text. Perl has many ways to eliminate indicies and in particular the 'C' style 'for(i=0;blah;blah){}' is particularly rare when processing text. Index operations and "off by one errors" are very common, if not the most common error in programming.

A Perl array can be viewed as a stack or a queue. You can push(),pop(),shift(),unshift() things on/off of a Perl array. Read about those functions - they a very fundamental to how Perl works (Perl variables are passed as a "stack" to a subroutine and they are shifted off - so you will see shift() often).

Instead of using indicies like $word[2] and $tag[2], below I show one way to do this without indicies at all! If you run out of tags before words, you will get an undefined value which will show up as an error since you are using "warnings" (which is an excellent idea).

So here is your code with very minimal changes. I used the DATA segment which is an already opened file handle and is often used in code like this rather than opening a separate file. I used a feature of Perl that allows documentation to be embedded in the code. You do not have to use either of these features, but they allowed me to have a single file with the code and the data and resulting printout. Just chalk this one up to "oh, its possible".

You will need to spew out some text before printing each line's block of html. That is a fixed header and footer. I think you can do that. You can use Perl print() or also printf(), or a "hereis" document.

#!/usr/bin/perl use strict; use warnings; my @tag_template = ('ID', 'Name', 'Major', 'Email'); #open FILE, '/home/ajb004/Paradigms/roster.txt' or die $!; while ( <DATA> ) { chomp; ## needed to get rid of \n on e-mail address my @word = split(/,/); #this is actually a regex my @tags = @tag_template; #copy is not a big deal here print "<TR>\n"; foreach my $word (@word) { $word =~ s/_/ /g; my $tag = shift(@tags); print " <TD>$tag: $word</TD>\n"; } print "</TR>\n"; } =Prints: <TR> <TD>ID: 123456</TD> <TD>Name: Susie Smith</TD> <TD>Major: Computer Science</TD> <TD>Email: ssmith@usomewhere.edu </TD> </TR> <TR> <TD>ID: 234567</TD> <TD>Name: John Smith</TD> <TD>Major: Computer Engineering</TD> <TD>Email: jsmith@usomewhere.edu</TD> </TR> =cut __DATA__ 123456,Susie_Smith,Computer_Science,ssmith@usomewhere.edu 234567,John_Smith,Computer_Engineering,jsmith@usomewhere.edu

Replies are listed 'Best First'.
Re^2: Help Me!
by jwkrahn (Abbot) on Apr 11, 2011 at 03:06 UTC

    You could do that without copying and shifting arrays:

    my @tags = qw( ID Name Major Email ); #open FILE, '/home/ajb004/Paradigms/roster.txt' or die $!; while ( <DATA> ) { chomp; ## needed to get rid of \n on e-mail address s/_/ /g; # this doesn't need to be in the inner loop my %fields; my @fields{ @tags } = split /,/; #this is actually a regex print "<TR>\n"; foreach my $tag ( @tags ) { print " <TD>$tag: $fields{$tag}</TD>\n"; } print "</TR>\n"; }
      Yes, but the OP is on his/her first Perl program. I don't see the need to use a hash in a first homework assignment - and especially not a hash slice which is certainly a more complex syntax than a simple hash assignment. Your code will not produce same order of output as the OP's code.

      I figure that 2, one dimensional arrays are just fine for this first homework. Don't make it more complex than it needs to be!

      updated: with strike-through.

        Your code will not produce same order of output as the OP's code.

        If by the same order of output you mean "ID" first, then "Name", "Major" and finally "Email", then yes, the code I posted produces the same order.    I guess you don't understand how arrays work?    Or foreach loops?