Xref: news2.mv.net comp.os.msdos.djgpp:8533 From: "John M. Aldrich" Newsgroups: comp.os.msdos.djgpp Subject: Re: Binary files and ^C chars-try again Date: Wed, 11 Sep 1996 19:04:03 -0700 Organization: Three pounds of chaos and a pinch of salt Lines: 123 Message-ID: <32376F93.7147@cs.com> References: <3237032D DOT 258A AT ccfsun DOT nrl DOT navy DOT mil> NNTP-Posting-Host: ppp211.cs.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: John Moon DJ-Gateway: from newsgroup comp.os.msdos.djgpp John Moon wrote: > > Let's try this again, > > This may be a dumb question, but > when I try to read a ^C char in binary from a > file I get an EOF condition, no matter if I try > to read further into the file or not. Is this a > perversity of the djgpp stdlib? If so, what is the > standard work-around? I have tried getc, fgetc, > fscanf, and fread, and they all do the same thing. > Apparently, the 255 (EOF) char does the same thing so > even if I get the file size and fseek past the > offending character I don't know whether it was a > ^C or EOF. Okay-- where should I start? > if((fp=fopen(argv[1],"w"))!=NULL) { > if((fp=fopen(argv[1],"r"))!=NULL) { 1) Your problem is caused by the fact that you are NOT opening the file in binary mode. Under DOS, binary and text modes are substantially different in the way they treat special characters like ^C and ^Z. Instead of "w" and "r", use "wb" and "rb" when you call fopen(). > I am using go32 v 1.12.maint3 2) The latest version of DJGPP is v2. There is no problem with using older versions, but be aware that they are not supported by the DJGPP development team anymore. The latest version is at: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2, /v2gnu, /v2misc, etc. Please download and read the file v2/readme.1st before getting any other files, and be sure to obtain the FAQ (v2/faq201b.zip) and read it as well for changes from v1.x to v2. > main(argc,argv) > int argc; > char *argv[]; 3) Why are you writing code for traditional C? The ANSI standard has been around more than long enough for all programmers to adopt it - it is easier, more intuitive, and makes it far easier to catch errors. Below I have made some recommended changes to your code. In case you wonder, I have tested this and it works. #include #include #include #define MAX 256 int main( int argc, char **argv ) { FILE *fp; long size; long i = 0; int j; char buf[MAX]; if ( argc < 2 ) { fprintf( stderr, "You must specify a filename.\n" ); exit( 1 ); } /* this creates a test binary file 0-255 named w/ contents of argv[1] */ if ( ( fp = fopen( argv[1], "wb" ) ) == NULL ) { perror( argv[1] ); exit( 1 ); } for ( i = 0; i < MAX; ++i ) fputc( (char) i, fp ); fclose( fp ); /* this attempts to read it back */ if ( ( fp = fopen( argv[1], "rb" ) ) == NULL ) { perror( argv[1] ); exit( 1 ); } size = filelength( fileno( fp ) ); printf( "\n\n\nFile Size = %ld\n", size ); for ( i = 0; ( j = fread( buf, (size_t) 1, (size_t) 1, fp ) ) > 0; ++i ) printf( "%ld %d %d\n", i, j, buf[0] ); /* * I don't think this is exactly what you want to do - are you trying to read the * characters one by one and fill up buf, or are you just reading them into the first * element of buf? If the former, then here's how you should do it. * * * for ( i = 0; ( j = fread( buf + i, (size_t) 1, (size_t) 1, fp ) > 0; ++i ) * printf( "%ld %d %d\n", i, j, buf[i] ); */ return 0; } -- Anything that happens, happens. Anything that, in happening, causes something else to happen, causes something else to happen. Anything that, in happening, causes itself to happen again, happens again. It doesn't necessarily do it in chronological order, though. --- Douglas Adams