9

I need to read and write binary data in C++.I use from ofstream and ifstream classes but it can't read some chars like 9,13,32.If is there another way to read and write theme.

Mahdi_Nine
  • 14,205
  • 26
  • 82
  • 117
  • 2
    Please show your code. Have you set `std::ifstream::binary` in the open-mode field? – Oliver Charlesworth Jun 13 '11 at 11:35
  • Please show a snippet of code, the output you expect and the output you got. – Fred Foo Jun 13 '11 at 11:35
  • please see http://stackoverflow.com/questions/5355163/writing-binary-data-stdstring-to-an-stdofstream – davka Jun 13 '11 at 11:50
  • The method I give in my answer works, but it performs relatively poorly. I would suggested reading the references the other answer gave because the functions mentioned actually perform a lot faster, though they are conceptually slightly more complex to use. – Omnifarious Jun 13 '11 at 20:57

3 Answers3

8

Open the file using the std::ios::binary flag and then use .read(buffer,length); and .write(buffer,length); rather than the streaming operators.

There are some examples here:

https://cplusplus.com/reference/istream/istream/read/

https://cplusplus.com/reference/ostream/ostream/write/

Anton Krug
  • 1,555
  • 2
  • 19
  • 32
Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
  • 2
    @mehdi, he gave you documentation and examples. What more do you want? – Beta Jun 13 '11 at 11:41
  • Look at the example in the first link. It will open a file, read the contents and put the contents in to a char buffer. The buffer will be treated as an array of bytes essentially. Exactly what is it that you need more explanation of? How to handle the buffer and take values from it? – rzetterberg Jun 13 '11 at 11:42
5

Here is a program that does this:

#include <iostream>
#include <fstream>

int main(int argc, const char *argv[])
{
   if (argc < 2) {
      ::std::cerr << "Usage: " << argv[0] << "<filename>\n";
      return 1;
   }
   ::std::ifstream in(argv[1], ::std::ios::binary);
   while (in) {
      char c;
      in.get(c);
      if (in) {
         ::std::cout << "Read a " << int(c) << "\n";
      }
   }
   return 0;
}

Here is an example of it being run in Linux:

$ echo -ne '\x9\xd\x20\x9\xd\x20\n' >binfile
$ ./readbin binfile 
Read a 9
Read a 13
Read a 32
Read a 9
Read a 13
Read a 32
Read a 10
Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • 15
    Paranoid namespace resolution! :-) – Kerrek SB Jun 13 '11 at 11:47
  • @Kerrek SB: Why, yes, see http://stackoverflow.com/questions/1661912/why-does-everybody-use-unanchored-namespace-declarations-i-e-std-not-std *big grin* – Omnifarious Jun 13 '11 at 11:56
  • 1
    This works, but is very inefficient if the file is large. For better performance, use Stuard Golodetz method. For even better performance, use std::streambuf. – Johan Råde Jun 13 '11 at 13:05
  • @user763305: Well, yes, it doesn't perform all that well. But the OP didn't seem in the mood for nuances. And the other answer just has links to documentation, so there is no method, just a hint as to how you might do it. :-) – Omnifarious Jun 13 '11 at 17:36
1

This is a basic example (without any error check!):

// Required STL
#include <fstream>
using namespace std;

// Just a class example
class Data
{
   int    a;
   double b;
};

// Create some variables as examples
Data x;
Data *y = new Data[10];

// Open the file in input/output
fstream myFile( "data.bin", ios::in | ios::out | ios::binary );

// Write at the beginning of the binary file
myFile.seekp(0);
myFile.write( (char*)&x, sizeof (Data) );

...

// Assume that we want read 10 Data since the beginning
// of the binary file:
myFile.seekg( 0 );
myFile.read( (char*)y, sizeof (Data) * 10 );

// Remember to close the file
myFile.close( );
gmas80
  • 1,218
  • 1
  • 14
  • 44