[comp.lang.c] What is wrong?

numork@ndsuvax.UUCP (James Mork) (01/24/89)

---
#include <stdio.h>
main(){
  FILE *fi, *ji;
  int i,j;
  fi=fopen("b:newtest.fil","w");
  for(i=0; i<200; i++) {
    j=putc(i,fi);
    printf("putting %d %d\n", i,j);};
  i=fclose(fi);
  printf("opening file for read...\n");
  ji=fopen("b:newtest.fil","r");
  for(i=0; i<200; i++) printf("i = %d  (read) = %d\n",i,getc(ji));
  i=fclose(ji);
};
---
  I am using TC 1.5 everything was going OK... Now... when I run
  a simple program like this, the file gets truncated after 25 or
  26 bytes...    After 25 when I read the file back in, I just
  get EOF (-1).  What is wrong?  Is this just some error that
  I am staring at, or is my compiler in foo bar land?
---
--
                  UUCP                Bitnet                Internet
          uunet!ndsuvax!numork    numork@ndsuvax     numork@plains.nodak.edu


#! rnews            597
Path: psuvm.bitnet!cunyvm!nyser!cmx!

ark@alice.UUCP (Andrew Koenig) (01/25/89)

In article <2051@ndsuvax.UUCP>, numork@ndsuvax.UUCP (James Mork) writes:
>   I am using TC 1.5 everything was going OK... Now... when I run
>   a simple program like this, the file gets truncated after 25 or
>   26 bytes...

Some MS-DOS C compilers treat a ^Z character as end of file.

^Z is 0x1A or 032 (octal) or 26 (decimal).  Your program
[not shown here] is putting consecutive characters into the
file, starting from 0.  Looks suspicious.
-- 
				--Andrew Koenig
				  ark@europa.att.com

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/25/89)

In article <2051@ndsuvax.UUCP> numork@ndsuvax.UUCP (James Mork) writes:
-    j=putc(i,fi);
-  a simple program like this, the file gets truncated after 25 or
-  26 bytes...    After 25 when I read the file back in, I just
-  get EOF (-1).  What is wrong?

Sounds to me like a ^Z in a text stream is taken as an EOF indicator.
I know CP/M had this misfeature; maybe PC-DOS does too.

You probably should have been using binary streams instead.
I.e. fopen with mode "wb" or "rb".

bobmon@iuvax.cs.indiana.edu (RAMontante) (01/25/89)

<9492@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>):
>In article <2051@ndsuvax.UUCP> numork@ndsuvax.UUCP (James Mork) writes:
	[ a living testament to the desirability of whitespace... ]
>-    j=putc(i,fi);
>-  a simple program like this, the file gets truncated after 25 or
>-  26 bytes...    After 25 when I read the file back in, I just
>-  get EOF (-1).  What is wrong?
>
>Sounds to me like a ^Z in a text stream is taken as an EOF indicator.
>I know CP/M had this misfeature; maybe PC-DOS does too.

MSDOS has exactly this feature; and it is an inheritance from CP/M.  BTW,
the file may actually have all 200 values in it.  Any debugger or hex-lister
program could show the actual contents.  But the test program will see the
27th byte, which is numbered 26, as the end-of-file character.

>You probably should have been using binary streams instead.
>I.e. fopen with mode "wb" or "rb".

Or (in Turbo C) set the external global variable "_fmode" equal to
"O_BINARY" as defined in fcntl.h.  This is described in the "fopen"
section of the TurboC reference manual.

charette@edsews.EDS.COM (Mark A. Charette) (01/25/89)

In article <9492@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
> In article <2051@ndsuvax.UUCP> numork@ndsuvax.UUCP (James Mork) writes:
>> -  a simple program like this, the file gets truncated after 25 or
>> -  26 bytes...    After 25 when I read the file back in, I just
>> -  get EOF (-1).  What is wrong?
>> 
> Sounds to me like a ^Z in a text stream is taken as an EOF indicator.
> I know CP/M had this misfeature; maybe PC-DOS does too.
> 
> You probably should have been using binary streams instead.
> I.e. fopen with mode "wb" or "rb".

PC/MS-DOS definately DOES have this misfeature. The "wb" / "rb" 'fix' as
suggested by Mr. Gwyn will solve the problem (I tested at home).

If a program does not have to access any files outside of it's own
requirements, the use of binary modes will save a lot of headaches for PC
programmers. In MS C, the default mode can be changes to binary, with the
resulting CR/LF translation problems and ^Z EOF marker 'fixed'.

-- 
Mark Charette             "People only like me when I'm dumb!", he said. 
Electronic Data Systems   "I like you a lot." was the reply.
750 Tower Drive           Voice: (313)265-7006        FAX: (313)265-5770
Troy, MI 48007-7019       charette@edsews.eds.com     uunet!edsews!charette 

svirsky@ttidca.TTI.COM (Bill Svirsky) (01/26/89)

In article <2051@ndsuvax.UUCP> numork@ndsuvax.UUCP (James Mork) writes:
+ #include <stdio.h+ 
+ main(){
+   FILE *fi, *ji;
+   int i,j;
+   fi=fopen("b:newtest.fil","w");
+   for(i=0; i<200; i++) {
+     j=putc(i,fi);
        ^
+     printf("putting %d %d\n", i,j);};
+   i=fclose(fi);
+   printf("opening file for read...\n");
+   ji=fopen("b:newtest.fil","r");
+   for(i=0; i<200; i++) printf("i = %d  (read) = %d\n",i,getc(ji));
                                                          ^
+   i=fclose(ji);
+ };
+ ---
+   I am using TC 1.5 everything was going OK... Now... when I run
+   a simple program like this, the file gets truncated after 25 or
+   26 bytes...    After 25 when I read the file back in, I just
+   get EOF (-1).  What is wrong?  Is this just some error that
+   I am staring at, or is my compiler in foo bar land?

A couple of problems.  putc and getc should be fputc and fgetc
respectively.  I imagine you copied those wrong, otherwise I don't see
how your program would have worked at all.  As to why your program stops
reading after 26 bytes, that is a little more subtle.  It just so
happens that MS-DOS uses ^Z (hex '1A', decimal 26) as it's EOF marker
when doing file I/O in TEXT mode.  Since you are opening the file to
read in TEXT mode (it is the default), MS-DOS returns EOF when it sees
it.  Either fopen the file as "rb" for BINARY mode, or set the global
variable _fmode to O_BINARY.  See the manual page for fopen.  You should
also fopen the output file in BINARY mode as "wb", because MS-DOS also
translates CR to a CR/LF combination when writing in TEXT mode and CR/LF
to a CR when reading.  See _fmode in your manual. 
-- 
Bill Svirsky, Citicorp+TTI, 3100 Ocean Park Blvd., Santa Monica, CA 90405
Work phone: 213-450-9111 x2597
svirsky@ttidca.tti.com | ...!{csun,psivax,rdlvax,retix}!ttidca!svirsky

dg@lakart.UUCP (David Goodenough) (01/26/89)

From article <2051@ndsuvax.UUCP>, by numork@ndsuvax.UUCP (James Mork):
>   I am using TC 1.5 everything was going OK... Now... when I run
>   a simple program like this, the file gets truncated after 25 or
>   26 bytes...    After 25 when I read the file back in, I just
>   get EOF (-1).  What is wrong?  Is this just some error that
>   I am staring at, or is my compiler in foo bar land?

The infamous MS-DOS (and CP/M) end of file problem. 26 is the magic number.
Early DOS programs and ALL CP/M programs that deal with text files do so in
complete blocks: 128 bytes at a time. So how do you deal with a text file
20 characters long? Easy: put the 20 characters in, and fill the rest of
the block with 0x1a. This means that anyone reading the file _IN TEXT MODE_
will see the first 0x1a as an end of file. In particular your putc(26, fp);
will put an EOF in a text file. NOW try doing the same with the files open
in binary mode (r+ or rb or whatever it is), and you may have somewhat
better luck.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

tcm@srhqla.UUCP (Tim Meighan) (01/27/89)

In article <8828@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:

>In article <2051@ndsuvax.UUCP>, numork@ndsuvax.UUCP (James Mork) writes:
>>   I am using TC 1.5 everything was going OK... Now... when I run
>>   a simple program like this, the file gets truncated after 25 or
>
>Some MS-DOS C compilers treat a ^Z character as end of file.

My understanding is that the end-of-file indication is being generated
by DOS and returned to the program; the compiler has nothing to do with
it.  This happens when the file is opened in text rather than binary
mode, which causes DOS to interperet ^Z as an EOF marker, among other
things.  In binary mode, DOS passes all characters without interpretation.
 
Also, I noticed a suggestion in another posting that James use fopen()
to solve the problem.  This could mean re-writing a lot of code, since
fopen() and open() use different file handling techniques.  While I am
not familiar with the TC compiler, it should allow you to open() a file
in binary with the "b" argument thus:

fp=open("MYFILE.TXT","r+b");

Tim Meighan
Network Operations
Silent Radio

svirsky@ttidca.TTI.COM (Bill Svirsky) (01/27/89)

In article <3756@ttidca.TTI.COM> svirsky@tab.tti.com (I) wrote:
[program, using putc and getc correctly, deleted]
>A couple of problems.  putc and getc should be fputc and fgetc
>respectively.  I imagine you copied those wrong, otherwise I don't see
>how your program would have worked at all.

Before I get blasted too badly for the above, I have already been shown
the error of my ways.  I do, in fact, know better.  I just wasn't thinking
clearly.  putc and getc were getting translated somewhere between the
screen and my mind into putchar and getchar.
-- 
Bill Svirsky, Citicorp+TTI, 3100 Ocean Park Blvd., Santa Monica, CA 90405
Work phone: 213-450-9111 x2597
svirsky@ttidca.tti.com | ...!{csun,psivax,rdlvax,retix}!ttidca!svirsky