Mitja
Mitja

Reputation: 873

c++ cout instead of fstream

Normally I live in my guarded world of C#. But sometimes I have to break out and do something outside.

At the moment I have to decode an audiostream and have to output this directly in my c++ console application.

If I write the content into a file, I can hear the correct result. But if I use instead of a fstream cout, I get only a noisy sound.

How I have to do it correct? Here the working filestream code:

fstream wavefile;
wavefile.open(output, ios::out | ios::binary | ios::trunc);

//do something
wavefile.write((char*) &waveheader, waveheadersize);
//do something else
do {
        //do something
        //decodedBuffer is of type BYTE* , decodedLength is of type DWORD
        wavefile.write((char*) decodedBuffer, decodedLength);
        wavefile.flush();
    } while (encodedLength > 0);

My not working cout code:

std::cout.setf(ios::out | ios::binary | ios::trunc);

//do something
//this works, I got the same output
cout << structToString(&waveheader) << endl;
//do something else
do {
        //do something
        cout << (char *)decodedBuffer;
    } while (encodedLength > 0);

Thanks in advance

Upvotes: 4

Views: 2567

Answers (3)

Deduplicator
Deduplicator

Reputation: 45664

First, there is absolutely no reason to use different code for a std::fstream and for std::cout (Beside which, your cout-code uses formatted output, and wrong):

You are using their ostream-interface in both cases.

So, first things first, repair the second code (as far as possible) by replacing it with the first.


Now, we come to the one difference (which you tried to paper over with setf): std::cout is in text-mode, not binary mode!

Unfortunately, none of ios::out, ios::binary and ios::trunc are formatting-flags, so you cannot set them with setf.

Actually, the mode cannot be changed at all after the fact (at least not portably).

Fortunately, you can simply ignore having the wrong mode on many systems, as Linux and others equate textmode and binary-mode. On windows, this hack should get you around it:

cout.flush();
fflush(stdout);
_setmode(_fileno(stdout), _O_BINARY);

Upvotes: 5

James Kanze
James Kanze

Reputation: 153919

The simple answer is that you can't. You need to output in binary mode. The mode is selected, once and for all, when you open the file, and std::cout is always opened in text mode.

Since you're just writing a block of bytes, the simplest solution is to use the system level requests. Under Windows, for example, you can use GetStdHandle( STD_OUTPUT_HANDLE ) to get the handle to standard out, and WriteFile to write a block of bytes to it. (Under Unix, the file descriptor for standard out is always 1, and the function is write. But since there is no difference between text mode and binary mode under Unix, I assume that this isn't your case.)

Upvotes: 1

m. c.
m. c.

Reputation: 895

Try this,

    std::cout.write(reinterpret_cast<char*>(decodedBuffer), decodedLength);

But I am not sure if structToString(&waveheader) work correctly, but you seem okay with it.

Upvotes: -2

Related Questions