0

I am working with two files, so as I loop through one I need to look through part of another one, and the information I encounter in it will be sequential. So I thought the best way would be to keep track of the line number:
open(PARSED, "< file.txt") or die$!;
my @parsedFile = < PARSED >;
my $line = 0;
my $size = @parsedFile;
# This next part is in a loop, but the only important thing is this next line
print $parsedFile[$line];

Even as the value of $line increases, it prints nothing but if I do the following there is no problem:
foreach (@parsedFile){ print $_; }
I have even tried a number of variations of trying to pull individual lines from @parsedFile but with no luck.

MCH
  • 2,124
  • 1
  • 19
  • 34
  • Am I missing something? By your example, `@parsedFile` only contains the string `file.txt`. Could you provide more info, so we can help you? – Linus Kleen Dec 19 '10 at 15:28
  • My mistake, fixed it, I was just hand copying a part of my program. – MCH Dec 19 '10 at 15:38
  • Your posted example prints first line of file just fine... I only had to put ; after ... – Dallaylaen Dec 19 '10 at 16:12
  • It's a very good idea to use 3 argument open with lexical filehandles. See http://stackoverflow.com/questions/1479741/why-is-three-argument-open-calls-with-lexical-filehandles-a-perl-best-practice for more info. – daotoad Dec 21 '10 at 00:21

3 Answers3

7

<> is an incredibly picky operator that does two very different things based solely on precise syntax of what's in the brackets. < PARSED > (with the extra spaces) is glob("PARSED"), not readline(PARSED), so your array is just getting the single string "PARSED".

(Assuming your posted code is accurate; it really helps if you copy and paste your actual not-working code, not re-type parts of it; it helps even more if your copy-and-pasted code can be run exactly as is to demonstrate your problem.)

Note that:

use warnings;
open(PARSED, "< filename") or die $!;
my @lines = < PARSED >;

will give you a warning that PARSED is used only once, a big clue that the <> isn't doing what you think.

ysth
  • 96,171
  • 6
  • 121
  • 214
  • +1 for pointing out the pickiness. still doesn't explain why it's supposedly working in a `foreach` loop though... – Linus Kleen Dec 19 '10 at 16:49
  • Thank you. I just rewrote all things related to that file and got it to work. – MCH Dec 19 '10 at 17:12
  • @goreSplatter: what is going wrong there is some nuance we don't have available for us to see, e.g. multiple `my @parsedFile`, misspellings, etc. – ysth Dec 19 '10 at 17:13
  • One more question, if you do something like my @lines = , can you no longer use ? Just to test it, afterwards I did while() but it seems to not enter this loop. – MCH Dec 21 '10 at 08:18
  • @NCH: you can use PARSED again, but it has reached the end of the file, so to read it again from the beginning you'd need to do `seek(PARSED,0,0)` first. – ysth Dec 21 '10 at 09:06
1

The original problem was fixed by ysth, but if the files aren't huge (you are reading them into memory, so I'm guessing not), why not use Tie::File instead of all those shenanigans?

use strict;
use warnings;
use 5.010;
use Tie::File;

tie my @parsedFile, 'Tie::File', 'file.txt' or die "Error: $!";

my $line = 0;
print $parsedFile[$line];
Hugmeir
  • 1,249
  • 6
  • 9
  • I'll keep this in mind for later use. The files I am using aren't too large. – MCH Dec 19 '10 at 17:12
  • alternatively, if the only use of the array is to iterate over it, why read the whole file in? – ysth Dec 19 '10 at 17:14
  • Well, I am checking for particular matches in the file and then I want to keep that string, and I don't know where the match will be. – MCH Dec 20 '10 at 05:05
0

To load the file lines in an array you need to open the file first:

open F,'<','file.txt' or die;
my @parsedFile = <F>;

The way you are doing it results in array parsedFile which contains only one element "file.txt" which is the name of the file.

codaddict
  • 445,704
  • 82
  • 492
  • 529