UH2@psuvm.psu.edu (Lee Sailer) (05/03/91)
The sybject line says most of i, I guess. MSDOS has that ittitating habit of adding a CR whenever it outputs a NL, which is fine until you try to write a program that writes a "binary" file to cout. I've tried the obvious things, without luck. For example cout << setiosflags(ios::binary) << "\n"; still sends a crlf pair to the stdout. I called Borland tech support, but they didn't seem to understand why one might ever wish to do what I want to do. So--in short. Can I turn off the \n --> \r\n translation for cout? lee
Lee Sailer <UH2@psuvm.psu.edu> (05/06/91)
For those of you who might be interested, it looks like this might be "impossible." I got several suggestions for the obvious workarounds, but I need the real solution in this case. Oh well. One response was especially interesting, and seemed like it might be of general enough interest that I've decided to post it here. I've edited it to preserve the authors anonymity. If he wanted it posted under his name, I guess he'd have done so. So, an anonymous author says.... I can't speak for the Borland library, but I think I can probably shed a little light on the subject for you. In general, once a stream/file is open with some mode, the only way to change its mode is to close it and reopen it. I know that at times this is a pain, but if you think about it, it is a necessary restriction. You see, there is a fair amount of machinery necessary to properly take care of (the idiotic) CR/LF translation for DOS. Low-level IO is probably the single largest source of bug reports in our library, and among those, CR/LF translation is a favorite. I spend an inordinate amount of time working on this code. It seems simple, but there are a huge number of problems associated with it. In addition, there may be systems on which the difference between text and binary files is more than just newline translation. For example, a system may require that all characters in a text file have the high bit clear. I can't think of such a system off hand, but it is possible and the ANSI C standard takes this into account. Anyway, once the machinery is set in motion, it may not be possible to change a file from text to binary mode without completely resetting the file. Rather than having the library do it "under the covers", the user is forced to do it by closing and reopening the file. This avoids unexpected surprises. I have considered this problem in relation to the C++ streams package, which supposedly makes it simple to modify the characteristics of a stream on the fly. My decision is that it is just too complex a problem to allow the text/binary mode to change after a file has been opened. I suspect that this is also the decision made by Borland. Granted, CR/LF translation is especially simple for output streams, but it is necessary to restrict the ability to change modes in order to keep the functionality of the library consistent. Otherwise people would be asking "Why can't I change cin to binary, it works for cout?". We are consistent in that you are not allowed to change the mode of a file, nor are you allowed to change the buffering status or the buffer size after the file has been used. Once the file has been used, the user can make no assumptions about the state of the buffer, therefore the user cannot expect to modify the buffering status. In the case of C++, the file mode is only interrogated when the file is opened, so modifying it later would have no effect. If you really need to make cout be a binary stream, I would suggest that you use the filebuf members (attach, etc.) to create a filebuf that suites your needs, then attach cout to that filebuf. Now that I look at the header files, this presents another problem -- there is no way to specify the mode of a file except in filebuf::open(). Since you want to use a descriptor set up by the runtime initializer, you can't use open(). So, you could use the filebuf constructor that takes a single 'int' argument and see what effective mode Borland gives you when you attach to handle 1. I think our library will by default give you a text stream unless you ask for a binary stream, so it wouldn't work under [author's] library. If this fails under Borland as well, you are left with two choices: 1) use a file instead of cout, or 2) get the source to Borland's runtime initializer and modify it to open handle 1 as binary. Sorry, I guess this pretty much turned out to be bad news. I will make a note of this problem so I can address it in our library, and I may pass it on to the ANSI committee if I can come up with a decent solution.
sking@nowhere.uucp (Steven King) (05/08/91)
In article <91126.163800UH2@psuvm.psu.edu> UH2@psuvm.psu.edu (Lee Sailer) writes: >For those of you who might be interested, it looks like this might be >"impossible." I got several suggestions for the obvious workarounds, but >I need the real solution in this case. Oh well. One response was >especially interesting, and seemed like it might be of general enough >interest that I've decided to post it here. I've edited it to >preserve the authors anonymity. If he wanted it posted under his >name, I guess he'd have done so. > >So, an anonymous author says.... > [ anon message why it might not be good to do this ] I dont know about borland, but microsoft c provides a "setmode" function in their C lib to do this, and it works on stdout. ie.: #include <iostream.h> extern "C" int setmode ( int, int ) ; #define O_BINARY 0x8000 main ( ) { cout << "foo\n" << flush ; setmode ( 1, O_BINARY ) ; cout << "foo bar\n" << flush ; } I would be very surprised if borland didnt provide something with the same functionality... -- If it don't stick, stink, or sting It ain't from Texas. ..!cs.utexas.edu!ut-emx!nowhere!sking
davidc@vlsisj.uucp (David Chapman) (05/09/91)
In article <91126.163800UH2@psuvm.psu.edu>, UH2@psuvm.psu.edu (Lee Sailer) writes: |> So, an anonymous author says.... |> |> with it. In addition, there may be systems on which the difference |> between text and binary files is more than just newline translation. Under VMS (a DEC operating system, in case you didn't know :-), text files are normally stored in VAR (variable length record) format. Every line has a length at the front of it. There really aren't any "newline" characters in the file and it's not possible to perform random accesses in this type of file (not that we've been able to figure out). Binary files are stored in fixed-length records, which you can seek in. |> Anyway, once the machinery is set in motion, it may not be possible |> to change a file from text to binary mode without completely resetting |> the file. Or rewriting the file completely. :-( David Chapman {known world}!decwrl!vlsisj!davidc vlsisj!davidc@decwrl.dec.com