chet@uwovax.uwo.ca (02/14/90)
I know I'll be embarrassed because of this, but would someone please tell me why program A below, when executed twice contains twenty lines (i.e. the 2nd ten lines are inserted before the EOF mark), but program B positions its appends after the EOF mark (so that they don't appear when the file is typed out)? And what I can do to fix B. This happens on Turbo C and Small C (2.2), and I presume on every C compiler. Please reply to creider@csd.uwo.ca Program A: #include <stdio.h> char entry[35]; main() { FILE *fp; int i; fp = fopen("tenlines.txt","a"); strcpy(entry,"this is an entry line"); for (i=0; i<10; i++) fprintf(fp, "%s\n", entry); fclose(fp); } ========================================== Prog B: #include <stdio.h> char entry[280]; char main_entry[40]; char lexical_class[20]; char eng_gloss[40]; char gram_info[80]; char semantic_fields[40]; char subent[80]; main() { FILE *fp; fp=fopen("lex3.db","a"); printf("\n\nMain entry: "); add_subentry(entry, main_entry); printf("Lexical class: "); add_subentry(entry, lexical_class); printf("English gloss: "); add_subentry(entry, eng_gloss); printf("Grammatical information: "); add_subentry(entry, gram_info); printf("Semantic fields: "); add_subentry(entry, semantic_fields); fprintf(fp, "%s\n", entry); fclose(fp); } add_subentry(entry, subentry) char *entry, *subentry; { gets(subentry); strcat(subentry,"$"); strcat(entry,subentry); } Many thanks, Chet Creider
wallace@oldtmr.dec.com (Ray Wallace) (02/14/90)
In article <4983.25d7e9db@uwovax.uwo.ca>, chet@uwovax.uwo.ca writes... >(i.e. the 2nd ten lines are inserted before the EOF mark), but program B >positions its appends after the EOF mark (so that they don't appear when >the file is typed out)? And what I can do to fix B. This happens on It looks to me like you need to add the line fprintf(fp, "%s\n", entry); to your add_subentry() function, and remove the fprintf() from the end of your main() function. As it was posted program B only writes to the file once, at the end of main() it writes out your "semantic_field". --- Ray Wallace (INTERNET,UUCP) wallace@oldtmr.enet.dec.com (UUCP) ...!decwrl!oldtmr.enet!wallace (INTERNET) wallace%oldtmr.enet@decwrl.dec.com ---
chet@uwovax.uwo.ca (02/15/90)
In message 14089 I noted a problem with the "a" mode. This is to confirm that the C compiler on the Unix OS I use (Sun 4.0.1_Export) behaves the same way. A (stupid) way around the problem is to open the file with "r+" and then read to EOF before executing the fprintf() statement: (to be inserted into program B:) while (!feof(fp)) fgets(dump, 240, fp); If this is done, with the Sun C compiler and with Turbo C (but not with Small C 2.2), then the EOF mark will be in the proper place. My questions with respect the different behaviour of A and B still remain as puzzles. Note also that the first reply to the query involved a misinterpretation of the code and is not relevant. Thanks again for any help. Appended below is a bit of lex3.db to show what B does: mtu$n.$person$watu$human$ kitu$n.$thing$vitu$entity$ ona$v.$see, look at$psv. onekana$perception$ mtoto$n.$child$watoto$human$ msichana$n.$girl$wasichana$human$ kijana$n.$youth$vijana$human$ chui$n.$leopard, cheetah$chui$animal$ Chet Creider creider@csd.uwo.ca
dfoster@jarthur.Claremont.EDU (Derek R. Foster) (02/15/90)
In article <4983.25d7e9db@uwovax.uwo.ca> chet@uwovax.uwo.ca writes: >I know I'll be embarrassed because of this, but would someone please >tell me why program A below, when executed twice contains twenty lines >(i.e. the 2nd ten lines are inserted before the EOF mark), but program B >positions its appends after the EOF mark (so that they don't appear when >the file is typed out)? And what I can do to fix B. This happens on >Turbo C and Small C (2.2), and I presume on every C compiler. >[program text follows] note: I attempted to mail this directly, but my host computer doesn't seem to believe uwovax.uwo.ca exists. I think it's useful enough information to post to the net, so I have. I don't know if this is a solution or not: just a suggestion of something that might be related to your problem. I don't see any reason why your two programs would definitely act differently. However, I do see a POSSIBLE reason why program B might act as described, along with a possible reason for A's working fine. The EOF marker character (ctrl-z on my system) is only meaningful in the case of text files. In a binary file, always adding text before an EOF character would be clearly inappropriate, since the character might actually be data in the file. Therefore, the C routines, if they do detection like this at all (which they may not - if so, see option #2 below.) must be able to tell which kind of file this is in order to tell if they should consider the EOF character to be the end of the file, or if they should judge file size by the "file length" field in the disk's directory entry. (which contains the ENTIRE length of the file, INCLUDING any EOF characters in the file as well as anything that may follow them.) possible solution 1: Try opening your file explicitly in text mode ie. stream = fopen(filename, "at"); if your C compiler is "smart" enough to know the difference, this may solve your problem. My logic here is that something in other routines in the program may have messed with the value of the _fmode system variable, which affects the default mode (text or binary) that the file was opened in. This would explain the results you describe. (if file A was opened in text mode, but file B was opened in binary mode.) If you state the mode explicitly, then you have at least removed this as a possible source of error. possible solution 2: "how do I get program B to work correctly" If that doesn't work, try using the fseek function to "back up" the stream pointer to before the EOF character. (assuming, of course, that there is one - using an actual character to mark the end of a text file has sort of gone out of style nowadays. Many editors don't automatically put one there anymore. Watch out for this.) /* WARNING : this code fragment assumes that the file in question a) has at least one byte in it. b) has no EOF characters occurring before the actual end-of-file (as reported by the disk directory entry) c) has an EOF character as the last byte in the file. if you aren't SURE of any of these assumptions, you may have to include additional code and/or file processing. */ stream = fopen(filename, "at"); fseek(stream,-1,SEEK_END); /* position the file pointer one before the end-of-file, so that the next character you write will overwrite the last character in the file */ My Turbo C manual states that fseek is "available on UNIX systems" so this should be fairly portable. Hope this helps! Derek Riippa Foster
zvs@bby.oz.au (Zev Sero) (02/16/90)
In a previous article chet@uwovax.uwo.ca writes: I know I'll be embarrassed because of this, but would someone please tell me why program A below, when executed twice contains twenty lines (i.e. the 2nd ten lines are inserted before the EOF mark), but program B positions its appends after the EOF mark (so that they don't appear when the file is typed out)? And what I can do to fix B. This happens on Turbo C and Small C (2.2), and I presume on every C compiler. [followed by example program A which works, and B which doesn't, even though the relevant code looks identical]. and in article <4992.25d9633c@uwovax.uwo.ca> he writes: In message 14089 I noted a problem with the "a" mode. This is to confirm that the C compiler on the Unix OS I use (Sun 4.0.1_Export) behaves the same way. Huh? In UNIX there is no such thing as an EOF marker, so how could "a" append after the EOF? I had assumed that your problem only happened in DOS. In any case, I compiled your program B with both gcc and cc under SunOS Release 4.0.3_EXPORT and also under Sun UNIX 4.2 Release 3.5EXPORT and it works fine in all four versions. -- Zev Sero - zvs@bby.oz.au Megalomaniacs are simply people who know damn well they can run the universe better then God or the present governors. - Abner Doon (Orson S. Card)