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

This is related to the solution arrived at in my previous question: http://www.perlmonks.org/?node_id=462126 When using the FileHandle module, you can getpos() and setpos() the current position in the file. I can't figure out exactly what it is that getpos() returns, only that using its value accurately resets setpos(). Anyhow, I read in a line from a text file using this:
$mypos = $myhandle->getpos(); $line = $myhandle->getline();
And then I want to find the first ; or / character in the line, and reset the position to that. I can find the index in $line of the character I'm looking for, but adding that to $mypos doesn't do what I thought it would do. Is there a way to convert that index into something I can add to $mypos and then use ->setpos($mypos)? Appreciate any help.

Replies are listed 'Best First'.
Re: FileHandle setpos function
by thundergnat (Deacon) on Jun 02, 2005 at 21:29 UTC

    Rather than getpos() and setpos(), I think you may have better luck with tell() and seek().

    Maybe this (very contrived) example will give you ideas.

    use strict; use warnings; use IO::File; use IO::Seekable; my $file = 'whatever.fil'; $/ =';'; my $fh = new IO::File; if ($fh->open("< $file")) { my $last = 0; while (<$fh>){ if ($_ =~ m|([^/]+/)|){ $fh->seek($last+$+[0],0); print $1,"\n"; }else{ print "$_\n"; } $last = $fh->tell; } $fh->close; }else{ die "$file not found. $!\n"; }

    Minor update to remove some unnecessary cruft.

Re: FileHandle setpos function
by fishbot_v2 (Chaplain) on Jun 02, 2005 at 21:42 UTC

    See ->seek( pos, SEEK_CUR ) in IO::Seekable. You can record your reference position, grab the index, then setpos(), then SEEK_CUR (which take a relative scalar position).

    What getpos() returns is an opaque value that is meaningful only to setpos.

    All that said, it sounds like you are doing this the hard way. Building a parser with seek calls seems like... something that you don't really want to do.

    Update: minor correction