Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Seeing next character in an file (http://www.velocityreviews.com/forums/t320156-seeing-next-character-in-an-file.html)

Grumfish 07-27-2003 01:09 AM

Seeing next character in an file
 
Is there a way to see the next character of an input file object without
advancing the position in the file?


Keith Jones 07-27-2003 02:58 AM

Re: Seeing next character in an file
 
On Sun, 27 Jul 2003 01:09:54 +0000, Grumfish wrote:

> Is there a way to see the next character of an input file object without
> advancing the position in the file?



To do this, you can do the following:

fin = file('myfile')

....

char = fin.read(1)
fin.seek(-1,1) # set the file's current position back a character

You can then write your own subclass of file, if you want, with "peek"
functionality:

class flexfile(file):
def __init__(self, fname, mode='r', bufsize=0):
file.__init__(self, fname, mode, bufsize)

def peek(self, cnt):
data = self.read(cnt)
self.seek(cnt * -1, 1)
return data

def peekline(self):
pos = self.tell()
data = self.readline()
self.seek(pos, 0)
return data










Bengt Richter 07-27-2003 05:36 PM

Re: Seeing next character in an file
 
On Sun, 27 Jul 2003 02:58:13 GMT, "Keith Jones" <kjones9@rochester.rr.com> wrote:

>On Sun, 27 Jul 2003 01:09:54 +0000, Grumfish wrote:
>
>> Is there a way to see the next character of an input file object without
>> advancing the position in the file?

>
>
>To do this, you can do the following:
>
>fin = file('myfile')
>
>...
>
>char = fin.read(1)
>fin.seek(-1,1) # set the file's current position back a character
>

Warning, though: this is very iffy on windows unless you have opened the file
in binary. E.g.,

>>> print >> file('ends_in_windows_EOL.txt','w'), 'Ends in windows EOL here:'


Look at it in binary:
>>> file('ends_in_windows_EOL.txt','rb').read()

'Ends in windows EOL here:\r\n'

Cooked:
>>> file('ends_in_windows_EOL.txt','r').read()

'Ends in windows EOL here:\n'

Now try to seek back past the apparent \n single character and one more (2)
so we can read the ':'
>>> f = file('ends_in_windows_EOL.txt')
>>> f.seek(-2, 2)
>>> f.read()

'\n'

Hm. That's a representation of reading the last two characters in cooked mode.
Apparently the seek positioned us to read '\r\n', not a cooked ':\n'

Look at the same in binary:
>>> f = file('ends_in_windows_EOL.txt', 'rb')
>>> f.seek(-2, 2)
>>> f.read()

'\r\n'

The last two are the windows EOL. Seeking -2 in cooked mode is not positioning at ':\n'
as we can see in the binary:

>>> f.seek(-3, 2)
>>> f.read()

':\r\n'

[...]

So if you're going to seek/tell, best to do it in binary, and deal with the platform dependent EOLs.

Regards,
Bengt Richter

Richie Hindle 07-28-2003 11:54 AM

Re: Seeing next character in an file
 

[Keith]
> def peek(self, cnt):
> data = self.read(cnt)
> self.seek(cnt * -1, 1)
> return data
>
> def peekline(self):
> pos = self.tell()
> data = self.readline()
> self.seek(pos, 0)
> return data


[Bengt]
> if you're going to seek/tell, best to do it in binary, and deal with the platform dependent EOLs.


seek() works perfectly with text-mode files as long as you only seek to
places given to you by tell(). So if Keith's peek() function had used
tell() and then seek()ed (sought()? 8-) back to that point like his
peekline() does, there would be no problem.

--
Richie Hindle
richie@entrian.com



R.Marquez 07-28-2003 02:25 PM

Re: Seeing next character in an file
 
Grumfish <nobody@nowhere.com> wrote in message news:<CDFUa.42241$wk4.27296@twister.nyroc.rr.com>. ..
> Is there a way to see the next character of an input file object without
> advancing the position in the file?


Here is a little class that I use on a little html parser that I
wrote. You may be able to adjust it for your needs:

class Characters:
def __init__(self, String):
self.Characters=String
self.Char = ""
self.index = 0
self.lenght = len(self.Characters)

def GetNextChar(self):
skipchar = 1
while skipchar ==1:
try:
self.Char = self.Characters[self.index]
except IndexError:
self.Char = None
#print "End of File\n"
return None
self.index += 1
if self.Char != "\n":
skipchar = 0
return self.Char

def CheckNextChar(self):
skipchar = 1
StartChar = self.Char
StartIndex = self.index
while skipchar ==1:
try:
self.Char = self.Characters[self.index]
except IndexError:
self.Char = None
#print "End of File\n"
return None
self.index += 1
if self.Char != "\n":
skipchar = 0
self.index = StartIndex
NextChar = self.Char
self.Char = StartChar
return NextChar

Richie Hindle 07-29-2003 08:05 AM

Re: Seeing next character in an file
 

[Richie]
> seek() works perfectly with text-mode files as long as you only seek to
> places given to you by tell(). So if Keith's peek() function had used
> tell() and then seek()ed (sought()? 8-) back to that point like his
> peekline() does, there would be no problem.


[Bengt]
> Can you cite a C or C++ standard section that guarantees that seek/tell
> will work that way in text mode? (I'm not saying there isn't one, but
> I couldn't find one quickly ;-)


ANSI C, ISO/IEC 9899:1990, section 7.9.9.2: "For a text stream, either
offset shall be zero, or offset shall be a value returned by an earlier
call to the ftell function on the same stream and whence shall be
SEEK_SET."

--
Richie Hindle
richie@entrian.com



Bengt Richter 07-29-2003 04:19 PM

Re: Seeing next character in an file
 
On Tue, 29 Jul 2003 09:05:53 +0100, Richie Hindle <richie@entrian.com> wrote:

>
>[Richie]
>> seek() works perfectly with text-mode files as long as you only seek to
>> places given to you by tell(). So if Keith's peek() function had used
>> tell() and then seek()ed (sought()? 8-) back to that point like his
>> peekline() does, there would be no problem.

>
>[Bengt]
>> Can you cite a C or C++ standard section that guarantees that seek/tell
>> will work that way in text mode? (I'm not saying there isn't one, but
>> I couldn't find one quickly ;-)

>
>ANSI C, ISO/IEC 9899:1990, section 7.9.9.2: "For a text stream, either
>offset shall be zero, or offset shall be a value returned by an earlier
>call to the ftell function on the same stream and whence shall be
>SEEK_SET."
>

Thank you. It makes sense that you could retrieve and set an underlying binary position
and decode forward with arbitrary cooking, so long as that cooking either goes character
by character and leaves the binary position to right after what it has used up, or does
the equivalent by proper binary repositioning if it grabs a chunk and doesn't use all of it
for a given cooking portion, so that the next retrieval (tell) will be valid.

I guess I must have been bitten some time in the foggy past, and never recovered trust.
Now I have enough at least to use it, though I will probably still want to write a little
verification into a unit test if I'm in finicky mode. Thanks again ;-)

BTW, is there an ANSI C spec available free on line (or an older, close-enough draft)?

Regards,
Bengt Richter

Richie Hindle 07-30-2003 09:01 AM

Re: Seeing next character in an file
 

[Bengt]
> BTW, is there an ANSI C spec available free on line
> (or an older, close-enough draft)?


Not a complete one that I'm aware of, no, although some pieces exist at
and around http://www.cs.vsb.cz/grygarek/tuox/s...si/Draft_g.txt

I eventually found the seek/tell rule in a book errata at
http://herd.plethora.net/~seebs/c/c_tcr.html then confirmed the standard
and section numbers with the "Normative Changes to ISO/IEC 9899:1990"
document at http://www.lysator.liu.se/c/tc1.html

I can't remember exactly what I googled for to find those documents (and
the query has already fallen off the end of my Google Toolbar's search
history - I think I use Google too much! 8-)

--
Richie Hindle
richie@entrian.com




All times are GMT. The time now is 06:02 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.