www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2003/01/03/16:05:42

Message-ID: <A0A49F49B15DD3118A9000805F95330D06CBE42B@fl51m02.space.honeywell.com>
From: "Younskevicius, Edward (FL51)" <Edward DOT Younskevicius AT honeywell DOT com>
To: djgpp AT delorie DOT com
Subject: Possible bug with fgets() and fputs(), ANSI C, in DJGPP
Date: Fri, 3 Jan 2003 16:05:17 -0500
MIME-Version: 1.0
X-Mailer: Internet Mail Service (5.5.2653.19)
Reply-To: djgpp AT delorie DOT com

Hello. Here is the description of what I think is a very peculiar bug, in
regards to the ANSI C fgets() and fputs() in DJGPP. I am reading a file in
(with fgets() ) line by line, until I find a particular word. Before I read
a particular line in, I save the position using fgetpos(). When I find the
line I am looking for (using strstr() to compare the current input line with
the word I am looking for), I rewind the file pointer to the beginning of
the line using fsetpos() and the position I saved earlier. I then modify the
input buffer I read in, changing the word I was looking for to another word
with the same number of characters. Then I write the modified line back out
to the input file, which has already been rewound to the beginning of the
line. Therefore the old line will be overwritten by the new one.

This is where things get weird. If I quit right at this moment, closing the
file before exit, the line is written out properly and the file has not
otherwise been changed or mangled. But if I continue and do another fgets(),
instead of getting the next line, I get half of the second line of the file
instead! (instead all of line 20 like I am expecting). If I do the fgets()
again right before the fputs(), I get the correct line, so fputs() somehow
must set my file pointer in some screwy way. Also, the file pointer is
always set to the same place in the file when fputs() messes the pointer up
(that is, in the middle of the second line of the file).

To further complicate matters, Cygwin + gcc 2.95 compiles my code and it
works perfectly, but using the Mingw switch (-mno-cygwin) I get a different
error where the file is read infinitely instead! You can imagine how much
all this vexes me, as I have programming for a good while now and rarely
have I come upon a bug so strange.

Here is the relevant code snippet if it will help. It is greatly simplified
(error checking and extraneous logic has been removed), but I think it has
all the relevant parts of the problem in it.

#define IO_BLOCK_SIZE 4096

FILE * odet_output;
char input_buffer[IO_BLOCK_SIZE + 1];
fpos_t begin_output_line;

fgetpos(odet_output, &begin_output_line); /* beginning of line 19 */

fgets(input_buffer, IO_BLOCK_SIZE, odet_output); /* read in line 19 */

search_pointer = (char *)strstr(input_buffer, "PASS/FAIL");

if(search_pointer != NULL)
{
	fsetpos(odet_output, &begin_output_line); /* reset file pointer to
beginning of line 19 */
	
	/* "PASS/FAIL" is nine characters, so overwrite nine characters */
	*search_pointer = 'P';
	*(search_pointer + 1) = 'a';
	*(search_pointer + 2) = 's';
	*(search_pointer + 3) = 's';
	*(search_pointer + 4) = ' ';
	*(search_pointer + 5) = ' ';
	*(search_pointer + 6) = ' ';
	*(search_pointer + 7) = ' ';
	*(search_pointer + 8) = ' ';
	
	fputs(input_buffer, odet_output); /* this is the line that makes the
file pointer, */
	                                              /* odet_output, get
set to some weird value */

	/* fgets() here would return half of line 2 instead of line 20 */
}

I am using the latest DJGPP and GNU tools from the website (DJGPP 2.03, GCC
3.21, BNU 2.13) on Windows 2000 Professional. I am using PCGrasp 6.2.17 as
my IDE, although I doubt it is relevant for this problem. As a quick bit of
background, I am tackling this problem for a parser I am writing for my job
in the US. Thank you in advance for any help you give me. Let me know if you
need more info. - Ed

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019