brand@janus.Berkeley.EDU (Graham Brand) (09/18/90)
I should like some help with a simple problem in Turbo C. I have a C program which I have been running on UNIX with no problem. I am trying to port it to Turbo C 2.0 running on my '386 under MSDOS (V3.3) but am having a strange problem. The program opens files for appending data using the: fopen(fp,filename,"a") construction and writes the data with the usual fprintf(fp,"%s ...%d\n",.....) instruction. The problem that I am having is that the line that is appended in the file is preceeded with a ^Z which makes the data invisible when a type command is issued from MSDOS. I can use vi and edit the file to remove the ^Z but don't want to have to do that every time. Can someone explain what is going on and propose a fix? Thanks in advance, Graham Brand (brand@janus.berkeley.edu)
edgincd2@mentor.cc.purdue.edu (Chris Edgington *Computer Science Major*) (09/18/90)
In article <38742@ucbvax.BERKELEY.EDU>, brand@janus.Berkeley.EDU (Graham Brand) writes: > instruction. The problem that I am having is that the line that is > appended in the file is preceeded with a ^Z which makes the data > invisible when a type command is issued from MSDOS. I can use vi and Is the ^Z leftover from the original dos file or is it the first character of the append data?? If it is leftover from the original file, you could you fsetpos to set the position for writing as eof(original)-1, then it would erase the ^Z Chris
toma@tekgvs.LABS.TEK.COM (Tom Almy) (09/19/90)
In article <38742@ucbvax.BERKELEY.EDU> brand@janus.Berkeley.EDU writes: >I should like some help with a simple problem in Turbo C. I have a >C program which I have been running on UNIX with no problem. I am >trying to port it to Turbo C 2.0 running on my '386 under MSDOS (V3.3) >but am having a strange problem. The program opens files for appending >data using the: I'm sure you mean fp=fopen(filename,"a") > fopen(fp,filename,"a") >construction and writes the data with the usual > fprintf(fp,"%s ...%d\n",.....) >instruction. The problem that I am having is that the line that is >appended in the file is preceeded with a ^Z which makes the data >invisible when a type command is issued from MSDOS. The file undoubtedly had the ^Z character at the end when you started. You can't delete it when opening in "a" mode because this mode forces all writes to occur at the end of file. You will need to do something like this: if (fp = fopen(filename,"r+") { /* file exists */ fseek(fp,-1L,SEEK_END); /* check last character */ if (fgetc(fp) == 26) /* last character is a control-Z, delete it */ fseek(fp,-1L,SEEK_END); } else { /* file does not already exist */ if ((fp = fopen(filename,"w")) == NULL) { /* Error code for unable to create file */ } } Tom Almy toma@tekgvs.labs.tek.com Standard Disclaimers Apply
darcy@druid.uucp (D'Arcy J.M. Cain) (09/20/90)
In article <14084@mentor.cc.purdue.edu> edgincd2@mentor.cc.purdue.edu (Chris Edgington *Computer Science Major*) writes: >In article <38742@ucbvax.BERKELEY.EDU>, brand@janus.Berkeley.EDU (Graham Brand) writes: >> instruction. The problem that I am having is that the line that is >> appended in the file is preceeded with a ^Z which makes the data >> invisible when a type command is issued from MSDOS. I can use vi and > >Is the ^Z leftover from the original dos file or is it the first character of >the append data?? If it is leftover from the original file, you could you >fsetpos to set the position for writing as eof(original)-1, then it would >erase the ^Z > But don't open the file in append mode. It repositions the file pointer to the end of the file before each write. Also you might want to check to see if the last character is a ^Z as well as the ones before the last. Some of those old programs use the CP/M method of filling a buffer with ^Zs before writing to it so you could have as many as 128 of them. This might work: long pos = 0; ... do { fseek(fp, --pos, SEEK_END) } while ((c = fgetc(fp)) == 0x1a); fseek(fp, ++pos, SEEK_END); That leaves the file pointing to the first of any ^Zs or the end of file if there are none. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay West Hill, Ontario, Canada | of operating systems. + 416 281 6094 |
otto@tukki.jyu.fi (Otto J. Makela) (09/20/90)
In article <1990Sep20.014132.29461@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes:
[how to position file to skip trailing ^Z's on brain-dead CP/M -like systems]
long pos = 0;
...
do { fseek(fp, --pos, SEEK_END) } while ((c = fgetc(fp)) == 0x1a);
fseek(fp, ++pos, SEEK_END);
Be careful with this stuff. Because you reseek as the last thing you do,
this will work. I have seen several C librarys which get confused when
you seek, read and then write a stream (probably some buffering messing
things up). Or is this perhaps (horror of horrors) standard behaviour ?
I wrote code like:
fseek(fp, -1L, SEEK_END);
while(fgetc(fp)==0x1A) fseek(fp, -2L, SEEK_CUR);
At this point I assumed the file would be positioned correctly. Didn't
work on DOS, didn't work on BSD Unix. I had to add:
fseek(fp, 0L, SEEK_CUR);
But you of course were aware of this.
--
* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * * * *
* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 2400/1200/300) *
* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE *
* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * * * *
karl@haddock.ima.isc.com (Karl Heuer) (09/22/90)
In article <OTTO.90Sep20180445@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes: >Be careful with this stuff... I have seen several C librarys which get >confused when you seek, read and then write a stream (probably some buffering >messing things up). Or is this perhaps (horror of horrors) standard >behaviour ? Yes. You can't switch between reading and writing unless you sync the stream first; fseek() is one way to do so. See 4.9.5.3 of the ANS. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
brand@janus.Berkeley.EDU (Graham Brand) (09/27/90)
Dear All, Thanks to the 6 or so of you who replied. No one respondent in particular was completely correct; the solution turned out to be a combination of things. Most people mentioned the history of CP/M and ^Z and so suggested using the fseek(fp,-1L,SEEK_END) approach. A couple suggested using the "b" access_mode option as in fp=fopen("filename","rb+"). The solution that worked uses both of these. I must admit that I am not too sure why, but having spent more time on this simple problem than I had intended, I shan't worry about it too much. Before I lay the problem to rest, though, there is one peculiar aspect that I have not resolved. It is the fact that, before I added the fixes to the program, even if I ensured that the file did **NOT** have a ^Z eof termination when I started, my program would prepend a ^Z to any line of text that was added to the end of the file. The only file operations that were done in the program were fopen() and fprintf()? Where was the ^Z coming from and which of the changes, fseek(.,-1L,.) or fopen(.,"b"), cured it? Thanks for all your help, -Graham
mgphl@msa3b.UUCP (Michael Phillips) (09/29/90)
brand@janus.Berkeley.EDU (Graham Brand) writes: >... >any line of text that was added to the end of the file. The only file >operations that were done in the program were fopen() and fprintf()? >Where was the ^Z coming from and which of the changes, fseek(.,-1L,.) or >fopen(.,"b"), cured it? >Thanks for all your help, >-Graham Graham, Absolutely, positively, it was the fopen(.,"b") that cured your ^Z problem. Since ^Z is the "end-of-file" marker for _TEXT_ files, anytime a file is opened as _text_ ("t", the usual default), and the file is updated in some way, it should have a ^Z appended to the end. Now I think that the ^Z is basically useless, but it is the way DOS defines things so I live with it. Michael *-----------------------------------------------------------------------* D&B Software Atlnata, GA - "Constants aren't and Variables don't"