write double variable into binary file in c++ - c++

I am trying to write double variable into a binary file. I am using below code:
double x = 1.;
ofstream mfout;
mfout.open("junk.bin", ios::out | ios::binary );
mfout.write((char*) &x, sizeof(double));
mfout.close();
What it returns to me after converting output binary file to ASCII is this:
.......
The third party software which has to read the file also returns error showing that there is problem. I would be thankful if someone guide me.

What it returns to me after converting output binary file to ASCII is this:
.......
No. That's what it returns to you if you interpret it as ASCII without converting it. Since it's not ASCII, interpreting it as ASCII will produce nonsense.
The third party software which has to read the file also returns error showing that there is problem.
Then it sounds like the third party software isn't expecting a binary file, since that's what you've written.
The file is binary, not ASCII. Only something expecting a single double in binary format (whatever binary format that your platform happens to use with your compiler options and so on) will be able to make sense out of it.

Related

C++ question: I'm having problems writing array of doubles (single precision 32 bit) to a disc file as 4-byte IEEE754 format

I have an application I'm trying to write in which will take a table of numbers (generated by user) and write the table to a file on disc. This file will then later be transferred to an Arduino AVR device over USB to its EEPROM.
The format I wish to save this information in on disc is 4-byte Little Endian as just raw Hex data. My table array called "tbl1Array[]" in my code below has been cast as a double.
Below is a snippet of the bunk code I have in place now, in-line following some array preparation code. The file open/close works fine, and in fact, data DOES get transferred to the file, but the format is not what I want.
ofstream fileToOutput("318file.bin");
for (int i=0; i<41; i++)
{
fileToOutput << tbl1Array[i];
}
fileToOutput.close();
THE PROBLEM is that what is written to the file is a hex ASCII representation of the decimal value. Not what I want! I don't know what I need to do to get my array as a nice neat concatenated list of 4-byte Little Endian words for my doubles that I can later read from within the Arduino code. I have a working method for transferring the file to the Arduino using AVRDUDE (tested and confirmed), so my only real hang-up is getting these doubles in my applications' array to 4-byte IEEE754 on disc. Any guidance would be greatly appreciated.
Regards - Mark
In a text stream, the new-line character is translated. Some operating systems translated to \r\n. A binary stream leaves it as it is.
Regardless of how you opened the stream – binary or text:
a. When you use the insertion/extraction operator the data is written as text. Assuming 0x01 is a one byte integer, ASCII 1 will be written (that is 0x31).
b. If you use the ostream::write method, you write the actual bytes; no translations happens. Assuming 0x01 is a one byte integer, 0x01 will be written.
If you want to write the actual bytes, open the stream in binary mode and use ostream::write:
ofstream os{ "out.bin", ios::binary };
if (!os)
return -1;
double d = 1.234567;
os.write((const char*)&d, sizeof d);
If you want to write the actual bytes as a string, open the stream in text mode and use the insertion operator:
ofstream os{ "out.txt" };
if (!os)
return -1;
double d = 1.234567;
static_assert(sizeof(double) == sizeof(long long));
os << hex << *reinterpret_cast<long long*>(&d);
If you want to write a double as string, using the maximum precision use:
os << setprecision(numeric_limits<double>::max_digits10) << d;
Don't use translated & untranslated methods on the same stream.
I do not know if all above examples will work on an Arduino compiler.

Reading the content of file other than ".txt" file

How can i read content of a file which is not a simple text file in c/c++? For example, I want to read image file such as .jpg/.png/.bmp and see the value at certain index,to check what colour it is? or if I have a .exe/.rar/.zip and want to know what value is stored at different indices?
I am aware of c style reading file, which is
FILE *fp;
fp = fopen("example.txt","r"); /* open for reading */
char c;
c = getc(fp) ;
I want to know if i replace "example.txt" with "image.png" or so, will it works? will i get correct data?
When you open a non-text file, you'll want to specify binary (untranslated) mode:
FILE *fp = fopen("example.png", "rb");
In a typical case, you do most of your reading from binary files by defining structs that mirror the structures in the file, and then using fread to read from the file into the structure (but this has to be done carefully, to ensure that things like padding in the struct don't differ between the representation in-memory and on-disk).
You would need to open the file in binary mode. This allows you to read the bytes in a "raw" mode where they are unchanged from what was in the file.
However, determining the color of a particular pixel, etc. requires that you fully understand the meaning of the bytes in the file and how they are arranged for the file being read. This second requirement is much more difficult. You'll need to do some research on the format of that file type in order to do that.
yea ofcorse you can open any file in binary mode in c. if you are interested then you can also read some 1st byte of any such non text file.
In most of the cases all different file-format has some fixed header so based on that you can identify the type of that file.
Open any matroska(.mkv) file and read 1st 4 byte you will always have this
0x1A 0x45 0xDF 0xA3
you can also see any file in binary representation hexdump utility in linux
====================
Edit:
such as .jpg/.png/.bmp and see the value at certain index,to
check what colour it is?
here you need to understand the format of that file and based on that you can know on which place's data what information is indicating..!!!

Reading bmp file for steganography

I am trying to read a bmp file in C++(Turbo). But i m not able to print binary stream.
I want to encode txt file into it and decrypt it.
How can i do this. I read that bmp file header is of 54 byte. But how and where should i append txt file in bmp file. ?
I know only Turbo C++, so it would be helpfull for me if u provide solution or suggestion related to topic for the same.
int main()
{
ifstream fr; //reads
ofstream fw; // wrrites to file
char c;
int random;
clrscr();
char file[2][100]={"s.bmp","s.txt"};
fr.open(file[0],ios::binary);//file name, mode of open, here input mode i.e. read only
if(!fr)
cout<<"File can not be opened.";
fw.open(file[1],ios::app);//file will be appended
if(!fw)
cout<<"File can not be opened";
while(!fr)
cout<<fr.get(); // error should be here. but not able to find out what error is it
fr.close();
fw.close();
getch();
}
This code is running fine when i pass txt file in binary mode
EDIT :
while(!fr)
cout<<fr.get();
I am not able to see binary data in console
this was working fine for text when i was passing character parameter in fr.get(c)
I think you question is allready answered:
Print an int in binary representation using C
convert your char to an int and you are done (at least for the output part)
With steganography, what little I know about it, you're not "appending" text. You're making subtle changes to the pixels (shading, etc..) to hide something that's not visually obvious, but should be able to be reverse-decrypted by examining the pixels. Should not have anything to do with the header.
So anyway, the point of my otherwise non-helpful answer is to encourage you go to and learn about the topic which you seek answers, so that you can design your solution, and THEN come and ask for specifics about implementation.
You need to modify the bit pattern, not append any text to the file.
One simple example :
Read the Bitmap Content (after header), and sacrifice a bit from each of the byte to hold your content
If on Windows, recode to use CreateFile and see what the real error is. If on Linux, ditto for open(2). Once you have debugged the problem you can probably shift back to iostreams.

Writing binary data

I am writing to binary file using fstream and when open the file using binary flag.
I needed to write some text as binary, which a simple write did the trick.
The problem is that I need also to write (as shown in hexadecimal) 0. The value when opened in binary notepad is shown zero, but when tried to write this the value not zero it was value of 30 in hexadecimal.
How you write specific data like this?
You probably just need something like this, improve as you see fit:
ofstream file("output.bin", ios::out | ios::binary);
if (file.good())
{
char buf[1] = {0};
file.write(buf, sizeof(buf));
file.close();
}
Links to more sophisticated solutions and documentation were already posted.
When you open the fstream use the ios::binary flag to specify binary output. More information can be found here.
As for writing 0, when you see 30 in hexidecimal you are writing the character '0', not the binary number 0. To do that with an fstream you can do something like:
my_fstream << 0;
Keep in mind the binary data 0 has no textual representation, so you will not be able to read it in Notepad like you would be able to read the character '0'.
Take a look at this:
http://www.cplusplus.com/forum/general/11272/

UCS-2LE text file parsing

I have a text file which was created using some Microsoft reporting tool. The text file includes the BOM 0xFFFE in the beginning and then ASCII character output with nulls between characters (i.e "F.i.e.l.d.1."). I can use iconv to convert this to UTF-8 using UCS-2LE as an input format and UTF-8 as an output format... it works great.
My problem is that I want to read in lines from the UCS-2LE file into strings and parse out the field values and then write them out to a ASCII text file (i.e. Field1 Field2). I have tried the string and wstring-based versions of getline – while it reads the string from the file, functions like substr(start, length) do interpret the string as 8-bit values, so the start and length values are off.
How do I read the UCS-2LE data into a C++ String and extract the data values? I have looked at boost and icu as well as numerous google searches but have not found anything that works. What am I missing here? Please help!
My example code looks like this:
wifstream srcFile;
srcFile.open(argv[1], ios_base::in | ios_base::binary);
..
..
wstring srcBuf;
..
..
while( getline(srcFile, srcBuf) )
{
wstring field1;
field1 = srcBuf.substr(12, 12);
...
...
}
So, if, for example, srcBuf contains "W.e. t.h.i.n.k. i.n. g.e.n.e.r.a.l.i.t.i.e.s." then the substr() above returns ".k. i.n. g.e" instead of "g.e.n.e.r.a.l.i.t.i.e.s.".
What I want is to read in the string and process it without having to worry about the multi-byte representation. Does anybody have an example of using boost (or something else) to read these strings from the file and convert them to a fixed width representation for internal use?
BTW, I am on a Mac using Eclipse and gcc.. Is it possible my STL does not understand wide character strings?
Thanks!
Having spent some good hours tackling this question, here are my conclusions:
Reading an UTF-16 (or UCS2-LE) file is apparently manageable in C++11, see How do I write a UTF-8 encoded string to a file in Windows, in C++
Since the boost::locale library is now part of C++11, one can just use codecvt_utf16 (see bullet below for eventual code samples)
However, in older compilers (e.g. MSVC 2008), you can use locale and a custom codecvt facet/"recipe", as very nicely exemplified in this answer to Writing UTF16 to file in binary mode
Alternatively, one can also try this method of reading, though it did not work in my case. The output would be missing lines which were replaced by garbage chars.
I wasn't able to get this done in my pre-C++11 compiler and had to resort to scripting it in Ruby and spawning a process (it's just in test so I think that kind of complications are ok there) to execute my task.
Hope this spares others some time, happy to help.
substr works fine for me on Linux with g++ 4.3.3. The program
#include <string>
#include <iostream>
using namespace std;
int main()
{
wstring s1 = L"Hello, world";
wstring s2 = s1.substr(3,5);
wcout << s2 << endl;
}
prints "lo, w" as it should.
However, the file reading probably does something different from what you expect. It converts the files from the locale encoding to wchar_t, which will cause each byte becoming its own wchar_t. I don't think the standard library supports reading UTF-16 into wchar_t.