[comp.lang.c] Help needed -> fseek

jwabik@umnd-cs.UUCP (02/12/87)

I'm trying to fseek my way around a large (1.5MB) file using VAX VMS C,
and am having absolutely NO LUCK.  

Background:
	I developed software on UNIX to does what I need.  The UNIX code
	works just fine (and MUCH faster) on the UNIX box.  I moved the file
	to VMS, made the few cosmetic changes (like pathnames, etc..) 
	required to compile.  No problem.  Execution, on the other hand .. 

	After much grieving, I've come to the conclusion that fseek() and
	ftell() don't work the same (if at all!) on VMS as they do on UNIX,
	even though the VMS C manual says, "Functionally Equivalent".

Precise Problem Statement:

	1)  File is opened properly. 
	2)  I've converted LONG ftell variables from UNIX to INT 
	    ftell variables for VMS.  I've followed other instructions
	    in the manual as well.
	3)  fseek(fp,n,0) does NOT bring me to byte n in the file.  If
	    I do something like:

		for (i=0; i<512; i++) printf("%c",getc(fp));

	    after the fseek, in 95% of the cases I end up with nulls
	    or blanks printed -- almost as if I fseeked to before BOF 
	    or to after EOF.  In the other 5% of the cases I end up with 
	    data from the file, but data that is clearly not even 
	    reasonablly close to n in fp.  A ftell(fp) directly 
	    following this loop always returns a BIZARRE value like 
	    (n+x), where x is in the range of 100000..300000, or -n.  

     I've been playing with this problem for a few weeks -- I've 
     tried every other type of reading fp (fscanf, fgets, etc..),
     and numerous other things that I've long since forgotten.. 
     Just when I have a method that appears to work in a test
     program, it fails in the real code..  

     Help!!!  8^)  

     Is there a limit to N in fseek(fp,N,0)?  (Aside from the limits
     of the 32 bit integer.)  What would cause a large ftell() skip
     by reading 512 bytes?  (large > 100000)  HOW CAN I MAKE THIS 
     TO WORK?  Might this be a compiler bug?  Has anyone else experienced
     this VMS snafoo?  

     Thanks in advance!

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- Jeff Wabik, UMD Computing Services.   | ihnp4 \                            =
= University of Minnesota, Duluth  55812|         umn-cs!umnd-cs!jwabik      -
- "I feel fine."  -Spock.  Boo.  Hiss!  | ????? /			     =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

forrest@blia.UUCP (02/12/87)

In article <384@umnd-cs-gw.umnd-cs.UUCP>, jwabik@umnd-cs.UUCP (Jeff Wabik) writes:
> I'm trying to fseek my way around a large (1.5MB) file using VAX VMS C,
> and am having absolutely NO LUCK.  
> 

Beware that seeking in non-stream files in VMS doesn't work the
way you'd expect based on Unix experiences. (See page 15-15 of the
"Programming in C" Manual.) If you think about it,
this makes sense for variable length record length files since you
have to know the record length for each record to be able to seek
over it. Although they could have provided a slow method for doing
forward seeking, doing backward seeking would be more trouble
than it's worth. Unix would have the same problem if they used
variable length record files, I believe.

What pisses me off is that seeking also doesn't work right with fixed
length record files. I don't understand the reasoning behind this.

Jon Forrest
ucbvax!mtxinu!blia!forrest

dlnash@ut-ngp.UUCP (02/12/87)

In article <384@umnd-cs-gw.umnd-cs.UUCP>, jwabik@umnd-cs.UUCP (Jeff Wabik) writes:
> I'm trying to fseek my way around a large (1.5MB) file using VAX VMS C,
> and am having absolutely NO LUCK.  
> 
> Precise Problem Statement:
> 
> 	1)  File is opened properly. 
> 	2)  I've converted LONG ftell variables from UNIX to INT 
> 	    ftell variables for VMS.  I've followed other instructions
> 	    in the manual as well.
> 	3)  fseek(fp,n,0) does NOT bring me to byte n in the file....
> 

VAX C manual p. 16-21:  "With record files, an fseek to a position that
was not returned by ftell causes unpredictable behavior."  I also tripped
over this problem.  If the file you are trying to fseek around in is not
a Stream_LF file, then fseek will only seek to record boundaries, not
character positions, or something broken like that.  If you brought the
data file over from another system, then it is probably not in Stream_LF
format.  The only way around this problem is to write a program which
does something like:

        while ((c = fgetc(in)) != EOF)
            fputc(c, out);

to make a copy of the file in Stream_LF format (which the stdio library
creates by default).  Then try fseeking around in the copy.  It's a
kludge, but it works.  BTW, don't rely on feof, it is broken too.  If
you read the last byte from a file, so that the next read will return
EOF, feof will not indicate the eof condition.  If you try to read and
get EOF, then try feof, it will indicate the eof condition.  That in my
mind is broken.  It should indicate eof when there is nothing left to
read, not after a read returns EOF. 

Oh, one more thing, make sure the variable 'c' in the above example is
an int, not a char.  The character 0xff is a perfectly valid character
on a machine with an 8-bit character set, especially if your are reading
and writing files with binary data in them.  Fgetc will return 0x000000ff
if the character it reads is 0xff.  The constant EOF is 0xffffffff.  The
above loop will work correctly only if 'c' is an int, not a char.

				Don Nash

UUCP:    ...!{ihnp4, allegra, seismo!ut-sally}!ut-ngp!dlnash
ARPA:    dlnash@ngp.CC.UTEXAS.EDU
BITNET:	 CCEU001@UTADNX, DLNASH@UTADNX

UUU       UUU
 U         U                The University of Texas at Austin
 U     TTTTUTTTTTTTTT              Computation Center
 U     T   U TT     T
  U       U  TT            "The world is basically non-linear."
   UUUUUUU   TT
             TT 
            TTTT

wong@rtech.UUCP (02/17/87)

In article <384@umnd-cs-gw.umnd-cs.UUCP> jwabik@umnd-cs.UUCP (Jeff Wabik) writes:
>I'm trying to fseek my way around a large (1.5MB) file using VAX VMS C,
>and am having absolutely NO LUCK.  
>

Yes, indeed.  The seek routines for VAX/VMS C work only as expected
for byte-stream files (a new file type DEC C supports.)  On record
files, they do not work the same (although they do do something.)
What 'ftell()' does on record files is return the byte offset of the
next record!  What 'fseek()' does on record files is seek to a given
record.  You can kind of kludge this to do what you want, but it's
not pretty (or even general.)


-- 
				J. Wong		ucbvax!mtxinu!rtech!wong

****************************************************************
You start a conversation, you can't even finish it.
You're talking alot, but you're not saying anything.
When I have nothing to say, my lips are sealed.
Say something once, why say it again.		- David Byrne