c++ gives me standard string/corrputed data instead of binary data when i tried to write 'const char *' [closed]

StackOverflow https://stackoverflow.com/questions/15760062

  •  31-03-2022
  •  | 
  •  

Question

In C++ (Visual C++ MFC) i have char * which is came from database. This is actually a picture. PostgreSQL returns it as char * because no byte[] in C++ (As for as i know -yet-:))

The thing is, i try to write that image like this one:

ofstream myFile ("C:\\picture.jpg", ios::out | ios::binary);
myFile.write(contents, size);
myFile.close();

It output like:

\xffd8ffe000104a46494600010101006000600000ffe1005a4578696600.......

I tried to change contents to reinterpret_cast<char *>(&contents) then i got few binary data like but just few. The rest of them is not in the file.

I also tried this one:

fstream binary_file("C:\\picture.jpg", ios::out | ios::binary | ios::app);
binary_file.write(reinterpret_cast<char *>(&contents),size);
binary_file.close();

For both with reinterpret_cast<char *>(&contents) or without it. Still got few byte data in the file. No more.

I also tried to change size. Size came from postgresql's PQgetlength method so it is true for sure. (Can't be wrong right?)

I finally give size myself and said to C++ that it is 5000. It output binary data with 5.000 but the fact is, it does not meet with original file. It starts with "h" and then something different...

I also tried to load this data to Chilkat's ByteArray and then write with its oen file access method. Still got same result with \xfdd....

So, what is the main goal? What am i missing here? Any help will be appreciated.

Edit: It is char *. Sorry for misunderstanding.

Conclusion: I choose Craig Ringer*'s solution due to my needs. But due to this question's nature i choose H2CO3's answer as an accepted answer.

Was it helpful?

Solution

If contents is really a char *, and not an array, then the problem is that you're passing the address of the pointer itself. And then you're trying to write the pointer value into the file. Pass contents (instead of &contents) to fstream::write().

OTHER TIPS

As far as I can see your output is messed up

\xffd8ffe000104a46494600010101006000600000ffe1005a4578696600...

this is no valid hex-notation. You would need something like this

\xff\xd8\xff\xe0\x00...

Use libpqtypes. It takes care of bytea conversion and all sorts of other higher level data type handling that isn't built in to libpq proper.

It's possible to use binary transfer mode in libpq, but honestly it's going to be much simpler to use libpqtypes and let it deal with all that. You really don't want to deal with binary transfer of dates and other custom format values, so if you do use binary transfer you should generally specify binary mode only for the bytea column(s).

First, your output looks like the start of a good, valid JPG file converted to the text with some self-made procedure. Some database developers don't like storing binary data in BLOBs, and the native PostreSQL format for storing binaries in text fields, bytea, is rather inconvenient. So many developers use Base64, UUENCODE, or self-made solutions.

And your first snippet looks OK. You gave us no definitions of contents and size, but if they are what they seem, it should work. It should output the contents without any alterations. So, to make sure the problem is in the contents, start the debugger, set a breakpoint at myFile.Write and look at contents variable. Most probably it will contain the same "\xffd8ffe000" instead of binary data.

If that is so, you need to manually reconvert this text data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top