Announcement

Collapse
No announcement yet.

Reading from a file after APPEND

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Peter Voll
    replied
    > APPEND was behaving different in PB/DOS, but you didn't know.

    What I meant to say was:
    You knew how APPEND was behaving in PB/DOS, but you didn't know that it was behaving different in PB/CC.

    Leave a comment:


  • Michael Mattias
    replied
    > APPEND was behaving different in PB/DOS, but you didn't know

    Oh yes I did.

    "Back in the day" (I really hate that phrase) I wrote more PB/DOS code than Carter's has little pills.

    However, when I migrated MS-DOS applications to PB/Windows, I made the time to RTFM.

    Maybe that also explains why I can be such a PITA when Doc<>RealLife.

    MCM

    Leave a comment:


  • Tom Hanlin
    replied
    Please note that the Ctrl+Z is considered an EOF, or end of file, regardless of where it is located in the physical file data. Checking for a Ctrl+Z as the last character(s) in the file will not be sufficient for all cases, although it may be sufficient for files you have created yourself.

    Leave a comment:


  • Peter Voll
    replied
    The reason for discussion this topic at all was, that APPEND was behaving different in PB/DOS, but you didn't know.
    So converting from PB/DOS to PB/CC was a problem, as you can't fix a problem, if you don't know there is a problem. So you are right, once you know about it, it isn't really a problem. But you have to know it !
    And because of the thread I'm referring back to , there is now an entry in the documentation describing this difference between PB/DOS and PB/CC...

    Leave a comment:


  • Michael Mattias
    replied
    Your SEEK
    >SEEK hFile, LOF(hFile) -1& ' position to last byte

    will position to the byte before the last byte.
    F.ex. If the length-of-file is 20 bytes, then the (possible) 0x1A will be in position 20. Your SEEK will position to byte 19, and the following GET wil read byte 19...
    You are correct. I usually work with OPEN FOR BINARY "BASE=0" but in deference to others I didn't use that in the OPEN here and must have screwed myself up by thinking one way here, one way there.

    Oh, well, whomever tried that surely has discovered it by now.

    >But of course, that is more than 8 years ago...

    Not just eight years, but three or four major compiler versions and updated help files.

    All I've ever asked for is that documented behavior equals actual behavior; when not true I call that a bug.

    Since the documentation now DOES explain the use of 0x1E as an 'end of file' indicator, I'd say that inconsistency has been addressed.

    The real point was, why whine about inconsistencies when it's so easy to just "deal with and be done with it?"

    MCM

    Leave a comment:


  • Peter Voll
    replied
    Hey Michael !

    I'm sorry if I misused the word "workaround", and you are right, english is not my mother tongue, but Daniel Raymer, who started this thread, asked for a "workaround", thats why I used the word...

    The code you are posting is very similar to the code I posted in the thread I was referring back to in my previous post in this thread, exept for one detail:
    Your SEEK
    SEEK hFile, LOF(hFile) -1& ' position to last byte
    will position to the byte before the last byte.
    F.ex. If the length-of-file is 20 bytes, then the (possible) 0x1A will be in position 20. Your SEEK will position to byte 19, and the following GET wil read byte 19...

    You say
    The word "workaround" should be reserved for use when dealing with a compiler bug ("issue"). No such "issue" here.
    In the thread, I refer back to, you were contributing in post #15 (Jan 22nd, 2002), and you said:
    Regardless, this is an inconsistency and should be addressed in a future version of the compilers.
    But of course, that is more than 8 years ago...

    Leave a comment:


  • Michael Mattias
    replied
    I don't know why the word "workaround" is being thrown around here so freely.

    The doc for LINE INPUT# (poor semantics*, but understandable in context) says...
    It is assumed the data is standard text, delimited by a CR/LF ($CRLF) or EOF (1A hex or $EOF).
    The doc for OPEN FOR APPEND says it will "append to" an existing file. For those for whom English is not your primary language, this means "add after the last byte currently in the file."

    Seems to me this is a case for "proper technique" and/or "understanding both the data I am working with and the behavior of the verbs I wish to use."

    If I had to append to a file which "might" have an EOF char (0x1A) at the end, and that were going to screw up the way I intend to read that file later - using LINE INPUT# - I would just eliminate the 0x1A before I started appending....

    Code:
      OPEN "thefile" FOR BINARY as hFile 
      SEEK hFile, LOF(hFile) -1&    ' position to last byte
      GET hFile, , bytevar      ' read last character
      IF btyevar = &h1A?  THEN  ' is the last char an EOF? 
        SEEK hFile, LOF(hFile) - 1& '  back up since our GET advanced 
        SETEOF  hFile                ' set new EOF prior to $EOF char 
      END IF 
      CLOSE hFile   ' save file with new length one less than before 
    
       Hfile = FREEFILE 
       OPEN  "thefile" FOR APPEND as hFIle 
       do my thing here 
       ....
    You might even write yourself a little procedure to "RemoveEofIfFound (Filename$) and keep this in your "Frequently #INCLUDEd Procedures" library. With minor modification you could truncate the file at the FIRST 0x1A found instead of looking only at the physical end of data.

    Was that so hard?

    The word "workaround" should be reserved for use when dealing with a compiler bug ("issue"). No such "issue" here.

    MCM
    *The data are assumed to be in "standard [CP/M but that would look really bad in the help for a Windows' compiler, wouldn't it?] text" format, with records delimited by CRLF; end of file is presumed at the first 0x1A found in the data or at the last byte of data in the file, whichever occurs first.

    Leave a comment:


  • Peter Voll
    replied
    EOF and APPEND and LINE INPUT

    FWIW, you migth want to read another discussion of this topic in:
    http://www.powerbasic.com/support/pb...ad.php?t=15450
    The 4th entry in this thread contains a workaround.
    Last edited by Peter Voll; 26 May 2010, 09:39 AM.

    Leave a comment:


  • Jim Dunn
    replied
    If you APPEND after a CHR$(26), the data gets written, but not read back (using MCM code from above) unless you read using FOR BINARY:
    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN() AS LONG
    
        LOCAL hFile AS LONG, nrec AS LONG, z AS LONG, s AS STRING
    
        ? "Creating THEFILE using 'FOR OUTPUT' with NO EOF marker added..."
        hFile = FREEFILE
        OPEN "THEFILE" FOR OUTPUT AS hFile
        FOR z = 1 TO 5
            s = USING$ ("Record Number A#", z)
            PRINT #hFile, s
        NEXT z
        s =  "No EOF MARKER inserted."
        PRINT #hFile, s
        CLOSE hFile
    
        ? "Appending 5 more records using 'FOR APPEND' and then adding EOF MARKER..."
        hFile = FREEFILE
        OPEN "THEFILE" FOR APPEND AS hFile
        FOR z = 1 TO 5
            s = USING$ ("Record Number B#", z)
            PRINT #hFile, s
        NEXT z
        s =  "EOF MARKER inserted here ->" & CHR$(26) & "<-"
        PRINT #hFile, s
        CLOSE hFILE
    
        ? "Appending 5 more records using 'FOR APPEND'"
        ? "(these C records *will* be written, but won't be read back"
        ? "because of the embedded EOF MARKER)"
        hFile = FREEFILE
        OPEN "THEFILE" FOR APPEND AS hFile
        FOR z = 1 TO 5
            s = USING$ ("Record Number C#", z)
            PRINT #hFile, s
        NEXT z
        CLOSE hFILE
    
        ? : ? "And reading THEFILE back using 'FOR INPUT':"
        hFile = FREEFILE
        OPEN "THEFILE" FOR INPUT AS hFile
        WHILE NOT EOF(hFile)
            LINE INPUT #hFile, s
            STDOUT s
        WEND
        CLOSE hFILE
    
        ? : ? "And reading THEFILE back using 'FOR BINARY':"
        hFile = FREEFILE
        OPEN "THEFILE" FOR BINARY AS hFile
        GET$ #hFile, LOF(#hFile), s
        CLOSE hFile
        STDOUT s
    
        WAITKEY$
    
    END FUNCTION
    The output is:
    Code:
    Creating THEFILE using 'FOR OUTPUT' with NO EOF marker added...
    Appending 5 more records using 'FOR APPEND' and then adding EOF MARKER...
    Appending 5 more records using 'FOR APPEND'
    (these C records *will* be written, but won't be read back
    because of the embedded EOF MARKER)
    
    And reading THEFILE back using 'FOR INPUT':
    Record Number A1
    Record Number A2
    Record Number A3
    Record Number A4
    Record Number A5
    No EOF MARKER inserted.
    Record Number B1
    Record Number B2
    Record Number B3
    Record Number B4
    Record Number B5
    EOF MARKER inserted here ->
    
    And reading THEFILE back using 'FOR BINARY':
    Record Number A1
    Record Number A2
    Record Number A3
    Record Number A4
    Record Number A5
    No EOF MARKER inserted.
    Record Number B1
    Record Number B2
    Record Number B3
    Record Number B4
    Record Number B5
    EOF MARKER inserted here ->→<-
    Record Number C1
    Record Number C2
    Record Number C3
    Record Number C4
    Record Number C5
    Last edited by Jim Dunn; 14 Mar 2010, 03:59 PM.

    Leave a comment:


  • Daniel Raymer
    replied
    Seems to work as before

    Lurkers - it seems to work as before. When I append to an existing file then use EOF(#) to read from it, I get the whole thing.

    Leave a comment:


  • Michael Mattias
    replied
    > SUB.... () AS LONG

    I do BIG IDEAS.

    Details are left to staff.

    Leave a comment:


  • John Montenigro
    replied
    MCM wrote:

    No, I did not try it...but this is the code I would use to try it.
    ummm -- that code's not going to cut it...

    Code:
    SUB Foo() AS LONG   <=== a typed SUB, cool!
    
    ... $CHR$(26)    <=== a constant function call?
    
    ...FOR Z = 11 TO 10    <=== which way did he go, which way did he go

    At least my misspelling of "cognitive" didn't prevent any program from working... Doncha just love tpyos! Can't publish with 'em, can't publish without 'em!

    Sarcasm aside, that's a useful demo. I learn (re-learn) something every day. (Nowadays it seems like I'm doing a lot more re-learning...)

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    SUB Foo() AS LONG
     LOCAL hFile AS LONG, nrec AS LONG, S AS STRING 
    
     hFile = FREEFILE 
     OPEN "THEFILE" FOR [b]OUTPUT[/b] AS hFile 
     FOR Z = 1 TO 10 
        S = USING$ ("Record NUmber  #", Z) 
        PRINT #hFile, S 
     NEXT 
    S =  "HERE COMES EOF MARKER" & $CHR$(26) & " SEE?"
    PRINT #hFile, S
    CLOSE hFile
    
    hFile = FREEFILE 
    OPEN "THEFILE" FOR [b]APPEND[/b] AS hFile 
     FOR Z = 11 TO 10 
        S = USING$ ("Record NUmber  #", Z) 
        PRINT #hFile, S 
     NEXT 
     CLOSE hFILE 
    
    hFile = FREEFILE 
    OPEN "THEFILE" FOR [b]INPUT[/b] AS hFile 
    WHILE NOT EOF(hFile) 
      LINE INPUT #hFile, S 
      STDOUT  S 
    WEND
    CLOSE hFILE 
    END SUB
    No, I did not try it...but this is the code I would use to try it.

    Leave a comment:


  • Chris Holbrook
    replied
    So what happens when you try it? does it rely on the ^Z character for EOF, or use the file length?

    Leave a comment:


  • Daniel Raymer
    started a topic Reading from a file after APPEND

    Reading from a file after APPEND

    PBCC5 manual says: When PB/CC opens a file for APPEND, it does not adjust the file pointer to overwrite any existing CHR$(26) character (end of file mark, $EOF). Instead, it places new data at the "true" end of the file. PB/DOS overwrites the CHR$(26) marker.

    So, when I read from a file I've appended to, and use NOT EOF to tell me if I've reached the end, it will stop before the appended material?

    Workaround, anyone? Of course, the obvious workaround is to not use APPEND......
Working...
X