More PERL Help...
Results 1 to 5 of 5

Thread: More PERL Help...

  1. #1
    Banned
    Join Date
    Oct 2001
    Posts
    1,462

    More PERL Help...

    Hmmm, I have a challenge (To me at least)...
    I need to make a perl program that reads the contentc of a text file and then prints them with a prefix (an incrementing number in front of each line)
    This is my code so far
    PHP Code:
    #!/usr/bin/perl
    #
    #
    $file '/root/perl/food';
    open(INFO$file);
    @
    lines = <INFO>;
    close(INFO);
    $i 0;
    foreach (@
    lines)
    {
    print 
    "$i $_";

    I got this far with much help, I know I need to make the $i variable increment every line, and I also know that I have to use $i++ to do it, I just dont know where top put it and why..... The file that is stated exists and has lines in it.... If anyone knows this please give me a hint or a tip... If your gonna give me the answer PLEASE explain it first.... Thanks in advance

    PS - Im just learning PERL so no wise cracks about the code

  2. #2
    str34m3r
    Guest
    Well, if you want the numbers in the file to start at 0, then you would put it immediately after the print statement but before the curly brace. Then the program will print your first line of text with a zero in front, then increment to one, then go to the next line of text and begin the loop again. The curly braces work just like they do in C, even though the foreach structure is new and different. Just think of it like a for loop where perl handles most of the work for you.

    And if you wanted the numbers to start at one (which makes more sense to me), then you would need to increment the variable right before the print statement. Did this help?

    Edit: And don't forget your semicolon after the $i++

  3. #3
    Senior Member
    Join Date
    Apr 2002
    Posts
    712
    Another approach (not to confuse you) is to shove a while loop right in the middle...

    ...something like...

    Code:
    while ( <FILEHANDLE> ){
      print( "$i: $_\n" );
      $i++;
    }
    \"Windows has detected that a gnat has farted in the general vicinity. You must reboot for changes to take affect. Reboot now?\"

  4. #4
    Senior Member
    Join Date
    Oct 2001
    Posts
    638
    Here's what I would do:

    Code:
    my($i) = 0;
    my($file) = "readme.txt";
    
    open(INFO, $file) || die "Error opening $file.";
    
    while (<INFO>) {
        printf("%.6d: %s\n", $i, $_);
        $i++;
    }
    
    close(INFO);
    Things to note:

    1.) Always use "my" to define the scope of your variables. You should be using "use strict;" anyway.

    2.) Always check that your file open has worked.

    3.) Using a while eliminate the need to use an array and is generally a better way of reading the file. @lines = <INFO>; is not a good way of doing this.

    4.) printf will let you print place markers so that the columns for the source print out all line up verticaly. Looks nicer.

    5.) You can put anything you want inside a foreach so you could have done:

    Code:
    foreach (@lines)
    {
    print "$i $_";
    $i++;
    }
    But why use extra variables when you don't need to.

    Hope this helps and may the source be with you .
    OpenBSD - The proactively secure operating system.

  5. #5
    Senior Member
    Join Date
    Apr 2002
    Posts
    712
    HeHe... I was trying to "give enough info to let acid 'take and run further' with it" - so now that the cat's out of the bag, so to speak, here's a couple small fixes as well... (no offense/etc to smirc... he posted some really good stuff)


    Originally posted here by smirc
    Here's what I would do:

    Code:
    my($i) = 0;
    my($file) = "readme.txt";
    
    open(INFO, $file) || die "Error opening $file.";
    
    while (<INFO>) {
        printf("%.6d: %s\n", $i, $_);
        $i++;
    }
    
    close(INFO);
    The open, technically, should explicitely declare how the file's to be opened and indicate the problem if the open fails... in this case, just read the file rather than trying to open a pipe or similiar:

    Code:
      open( INFO, "< ${file}" ) || die( "Can't open file \"$file\" - Error was \"$!\" );
    The while loop will have a small problem with the EOL characters in a multi-line file... should probably trim those, as well...

    Code:
    while( <INFO> ){
      chomp( $_ );
      printf("%.6d: %s\n", $i, $_);
      $i++
    }
    Technically, to limit the lines, the increment operator can be thrown in to the print statement, but I think that starts to cross the line on readability versus functionality.

    Things to note:

    1.) Always use "my" to define the scope of your variables. You should be using "use strict;" anyway.
    perl -w is also a good one to get in the habit of using.

    2.) Always check that your file open has worked.
    I'd expand that to "always check that something unexpected hasn't happened when depending on externally influenced data. Just because your web for says "only accept a five-digit number" it doesn't mean some smart-a** won't try to feed you some other unexpected info another way.

    3.) Using a while eliminate the need to use an array and is generally a better way of reading the file. @lines = <INFO>; is not a good way of doing this.
    The array method here is "expensive." For a suitably large file, it can kill the process/machine. Reading the file iteratively and discarding things after you are done with them is much kinder.

    4.) printf will let you print place markers so that the columns for the source print out all line up verticaly. Looks nicer.
    The caveat here is that print formatting is slow. It's great to use when you need it, but it's better to use "print" when you can get away with it. Abuse of "printf" will slow a routine down to the point that you can see it (I used to do everything using printf's); use it sparingly and you're fine.
    \"Windows has detected that a gnat has farted in the general vicinity. You must reboot for changes to take affect. Reboot now?\"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •