ginocapelli has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am trying to figure out how to read data from a new line instead of after a specified character. Here is the script:
$adfile = 'banners.dat'; open(FILE, $adfile) || die "Can't open $adfile"; $file = <FILE>; close(FILE); @stuff = split(/;/,$file); srand(time ^ $$); $choice = rand(@stuff); $chosen = @stuff[$choice]; @part = split(/\|/,$chosen); print "Content-type: text/html\n\n"; print "<font face=\"arial\" size=\"2\"><a href=\"@part[0]\" target +=\"_blank\"><img src=\"@part[1]\" width=\"@part[2]\" height=\"@part[3 +]\" alt=\"@part[4]\" border=\"1\"><br>Please visit my sponosr! </a></ +font>\n";
and here is what the data file looks like:
http://www.whatever.com|whatever.gif|468|60|whatever;http://www.okay.c +a|okay.gif|468|60|okay
I don't want a huge line of code for all the banners that will be displayed. Instead, I would line to enter the info like this:
http://www.whatever.com|whatever.gif|468|60|whatever http://www.okay.ca|okay.gif|468|60|okay
How can I do this? Anyone? Thanks!

Replies are listed 'Best First'.
Re: telling script to read from next line
by andreychek (Parson) on Jul 08, 2001 at 05:19 UTC
    I'm going to offer a two part answer. I'll first answer the question you asked, then I'll answer what it looks like you're really trying to do with your code :-)

    1. The question you asked -- how to read data from a newline -- I think you may be making this problem harder then it is. Perl will gladly work with you on this. In fact, by default, it does read line by line, unless you tell it differently. As an example, check out this code:
    # You are using strict, right??? :-) use strict; my $adfile = 'banners.dat'; open(FILE, $adfile) || die "Can't open $adfile"; # Loops through the data file, 1 line at a time while(<FILE>) { # Split apart the line of data, put it in an array my @part = split(/\|/, $_); # Print's the url from the data line print "$part[0]\n"; } # Close up the file close(FILE);
    That code will loop through your data file, line by line. By the time it's finished executing, it will print the url from each line of your data file.

    However, it doesn't appear that you need to do something with each line, it appears that you want to pick out a random line from your data file, and do something with it. And you're in luck, because it just so happens that this information is in the FAQ. All you have to do to get a random line from your file is this:
    srand; # This chooses a random line, and puts that line into # the var $line. rand($.) < 1 && ($line = $_) while <FILE>; # Now you can split it my @part = split(/\|/,$line); # And then do whatever else with it... print "$part[0] $part[1] $part[2] ... ";
    As a final note, I noticed that you were accessing elements in the @part array by using syntax like @array[0]. Actually, the correct syntax to access a single element in an array is $array[0] and $array[1]. It's using the $, instead of the @. The @ is for referring to an entire array or array slice. The $ is used to refer to one, scalar value, such as a single element in an array.

    Hope that helps!
    -Eric
      Thanks a lot. Here is what I am using and it is working fine:
      #!/usr/bin/perl -wT use strict; use CGI; my $line = ""; my $part = ""; my $adfile = 'banners.dat'; open(FILE, $adfile) || die "Can't open $adfile"; #srand; # This chooses a random line, and puts that line into # the var $line. rand($.) < 1 && ($line = $_) while <FILE>; my @part = split(/\|/,$line); # Display the banner print "Content-type: text/html\n\n"; print "<font face=\"arial\" size=\"2\"><a href=\"@part[0]\" target +=\"_blank\"><img src=\"@part[1]\" width=\"@part[2]\" height=\"@part[3 +]\" alt=\"@part[4]\" border=\"1\"><br>Please visit my sponosr! </a></ +font>\n"; # Close the file close(FILE);
      Thanks to everyone who repsonded to this.
      Thanks!
Re: telling script to read from next line
by Zaxo (Archbishop) on Jul 08, 2001 at 05:56 UTC

    You will need to rewrite your data file to get records separated by newlines. As an alternative, you can redefine perl's idea of an input record.

    You can set the input record separator, $/ to your file's delimiter, here ';'. local should be used since $/ is a global.

    { local $/ = ';'; # input record separator - this is what chomp eats local $\ = "\n"; open(FILE, $adfile) || die "Can't open $adfile", $!; open(NEWFILE, "> $adfile.new") || die "Can't open new $adfile", $! +; while (<FILE>) { chomp; print NEWFILE; } close(NEWFILE>; close(FILE); }

    The example here writes you a new data file with newlines.

    After Compline,
    Zaxo

    Update: repaired loss of last record if ';' not present

Re: telling script to read from next line
by tomhukins (Curate) on Jul 08, 2001 at 15:28 UTC

    There's no need to use srand in your code any more. perlfunc:srand says:

    It's usually not necessary to call C<srand()> at all, because if it is not called explicitly, it is called implicitly at the first use of the C<rand()> operator. However, this was not the case in version of Perl before 5.004
    So, unless you intend to run this code on using very old versions of Perl, you're better off without this call.

Re: telling script to read from next line
by I0 (Priest) on Jul 08, 2001 at 10:16 UTC
    @stuff = <FILE>;

      If you're working with large files, this is a bad idea, as the whole file will be read into memory. As others have suggested, it's better to do:

      while (<FILE>) { # do something here }
      because this won't use so much memory.