Seeing next character in an file

Discussion in 'Python' started by Grumfish, Jul 27, 2003.

  1. Grumfish

    Grumfish Guest

    Is there a way to see the next character of an input file object without
    advancing the position in the file?
    Grumfish, Jul 27, 2003
    #1
    1. Advertising

  2. Grumfish

    Keith Jones Guest

    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
    Keith Jones, Jul 27, 2003
    #2
    1. Advertising

  3. On Sun, 27 Jul 2003 02:58:13 GMT, "Keith Jones" <> 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
    Bengt Richter, Jul 27, 2003
    #3
  4. [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()? :cool: back to that point like his
    peekline() does, there would be no problem.

    --
    Richie Hindle
    Richie Hindle, Jul 28, 2003
    #4
  5. Grumfish

    R.Marquez Guest

    Grumfish <> wrote in message news:<CDFUa.42241$>...
    > 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
    R.Marquez, Jul 28, 2003
    #5
  6. [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()? :cool: 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 Hindle, Jul 29, 2003
    #6
  7. On Tue, 29 Jul 2003 09:05:53 +0100, Richie Hindle <> 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()? :cool: 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
    Bengt Richter, Jul 29, 2003
    #7
  8. [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/sources/lib/ansi/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! :cool:

    --
    Richie Hindle
    Richie Hindle, Jul 30, 2003
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. darrel
    Replies:
    1
    Views:
    469
    bruce barker \(sqlwork.com\)
    May 8, 2006
  2. Deniz Bahar
    Replies:
    2
    Views:
    443
    Andrey Tarasevich
    Mar 9, 2005
  3. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki

    Reading of file by next of map file and by next of file descriptor.

    =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki, Jul 10, 2007, in forum: C++
    Replies:
    1
    Views:
    768
    Alf P. Steinbach
    Jul 10, 2007
  4. Tad McClellan
    Replies:
    3
    Views:
    126
    Edward Wijaya
    May 13, 2004
  5. Liora
    Replies:
    5
    Views:
    601
    Tad McClellan
    Jan 12, 2007
Loading...

Share This Page