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.

4
  • Am I missing something? By your example, @parsedFile only contains the string file.txt. Could you provide more info, so we can help you? Commented Dec 19, 2010 at 15:28
  • My mistake, fixed it, I was just hand copying a part of my program. Commented Dec 19, 2010 at 15:38
  • Your posted example prints first line of file just fine... I only had to put ; after <PARSED>... Commented Dec 19, 2010 at 16:12
  • It's a very good idea to use 3 argument open with lexical filehandles. See stackoverflow.com/questions/1479741/… for more info. Commented Dec 21, 2010 at 0:21

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

5 Comments

+1 for pointing out the pickiness. still doesn't explain why it's supposedly working in a foreach loop though...
Thank you. I just rewrote all things related to that file and got it to work.
@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.
One more question, if you do something like my @lines = <PARSED>, can you no longer use <PARSED>? Just to test it, afterwards I did while(<PARSED>) but it seems to not enter this loop.
@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.
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];

3 Comments

I'll keep this in mind for later use. The files I am using aren't too large.
alternatively, if the only use of the array is to iterate over it, why read the whole file in?
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.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.