how to write binary data to stdout?


R

Rouben Rostamian

Consider the following demo program:

#include <stdio.h>

int main(void)
{
unsigned char c;

for (c=0; c<15; c++)
putchar(c);
return 0;
}

As is, the output of the program is platform-dependent.
For instance, in the UNIX environment, it puts 15 characters
to stdout. Under windows it puts out at least 16, because c=10
gets translated to newline+carriage return.

This brings me to:

Question: Is it possible to close stdout then reopen it in binary
mode in a platform-independent way?

If that were possible, then the binary-mode output of the program
would be the same on all platforms.

The purpose of my real program (not this demo,) is to act as a
filter from stdin to stdout, therefore fopen(filename, "wb") is
of not much help.
 
Ad

Advertisements

J

James Hu

Question: Is it possible to close stdout then reopen it in binary
mode in a platform-independent way?

No.

If you are seeking a completely standard solution, you are better off
outputting a text encoding of the binary data. If you are writing
programs intended to read each others input/output, the receiving
program would need to decode the stream.

-- James
 
I

Irrwahn Grausewitz

(e-mail address removed) (Rouben Rostamian) wrote:

Question: Is it possible to close stdout then reopen it in binary
mode in a platform-independent way?

Well, there are two problems:

1) stdout need not be a modifiable lvalue, so you can't just
use fopen - you cannot come up with a suitable filename anyway.
To solve this, one could come up with
reopen( NULL, "wb", stdout);
running into problem number

2) It is implementation defined which (if any) and under what
circumstances mode changes are permitted.
If that were possible, then the binary-mode output of the program
would be the same on all platforms.

That would be great, but unfortunately it's impossible. stdin,
stdout and stderr are text streams per definition, and there is
no portable way to switch them to binary mode.
The purpose of my real program (not this demo,) is to act as a
filter from stdin to stdout, therefore fopen(filename, "wb") is
of not much help.

I cannot come up with a better solution, sorry.

Regards
 
C

CBFalconer

Rouben said:
Consider the following demo program:

#include <stdio.h>

int main(void)
{
unsigned char c;
for (c=0; c<15; c++) putchar(c);
return 0;
}

As is, the output of the program is platform-dependent.
For instance, in the UNIX environment, it puts 15 characters
to stdout. Under windows it puts out at least 16, because c=10
gets translated to newline+carriage return.

This brings me to:

Question: Is it possible to close stdout then reopen it in binary
mode in a platform-independent way?

If that were possible, then the binary-mode output of the program
would be the same on all platforms.

The purpose of my real program (not this demo,) is to act as a
filter from stdin to stdout, therefore fopen(filename, "wb") is
of not much help.

This is handled by freopen.

if (freopen(NULL, "wb", stdout)) {...}

Note that it may fail, and has some implementation dependancies.
From N869:

7.19.5.4 The freopen function

Synopsis
[#1]
#include <stdio.h>
FILE *freopen(const char * filename,
const char * mode,
FILE * restrict stream);

Description

[#2] The freopen function opens the file whose name is the
string pointed to by filename and associates the stream
pointed to by stream with it. The mode argument is used
just as in the fopen function.215)

____________________

215The primary use of the freopen function is to change the
file associated with a standard text stream (stderr,
stdin, or stdout), as those identifiers need not be
modifiable lvalues to which the value returned by the
fopen function may be assigned.


[#3] If filename is a null pointer, the freopen function
attempts to change the mode of the stream to that specified
by mode, as if the name of the file currently associated
with the stream had been used. It is implementation-defined
which changes of mode are permitted (if any), and under what
circumstances.

[#4] The freopen function first attempts to close any file
that is associated with the specified stream. Failure to
close the file is ignored. The error and end-of-file
indicators for the stream are cleared.

Returns

[#5] The freopen function returns a null pointer if the open
operation fails. Otherwise, freopen returns the value of
stream.
 
Ad

Advertisements

R

Richard Bos

CBFalconer said:
This is handled by freopen.

if (freopen(NULL, "wb", stdout)) {...}

Note that it may fail, and has some implementation dependancies.

One of which is that a null first argument to freopen() is a C99
feature.

Richard
 

Top