Jump to content
  • Advertisement
Sign in to follow this  
iansane

how to read binary into a vector for manipulation?

This topic is 3643 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I want to read the binary of a file into a vector so I can make an encryption and decryption algorithm to encrypt the binary. Not sure if that is the right way to do it. I am trying to use the following code from cplusplus.com, but to write it to a vector instead of a memory block. Can anyone tell me how to do this? I tried vector.push_back(memblock) and it seems to be working but I get an error at run time saying the program needs to close. I don't think I'm understanding how it works. Do I need to read into another variable to use with push_back?
// reading a complete binary file
#include <iostream>
#include <fstream>
using namespace std;

ifstream::pos_type size;
char * memblock;

int main () {
  ifstream file ("example.txt", ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    cout << "the complete file content is in memory";

    delete[] memblock;
  }
  else cout << "Unable to open file";
  return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
You could read the data into the buffer, as you're doing, then move it to the vector. One way to do it is:

#include <vector>

....your file open/read code here...

vector<char> buf;
buf.insert(buf.begin(), size, (const char &)memblock);

....manipulate can happen now...

You could also do it one character at a time, using push_back, but the above should be faster.

Share this post


Link to post
Share on other sites
Thanks OldGuy

I figured out the push_back way after a few errors about converting char to char.

I'll try this way too.

Thanks a lot

Share this post


Link to post
Share on other sites
I'd recommend you use unsigned chars if you are just dealing with bits. Char can be either unsigned or signed by default, and that can cause some issues if your algorithm is doing any right shifting or any arithmetic.

Share this post


Link to post
Share on other sites
Rather than mess about with a raw array, you could just read into a vector in the first place:


int main () {
ifstream file ("example.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();

// memblock = new char [size];
std::vector<char> memblock(size);

file.seekg (0, ios::beg);

// file.read (memblock, size);
file.read(&(memblock[0]),size);

file.close();

cout << "the complete file content is in memory";

// next line is now obsolete
// delete[] memblock;
}
else cout << "Unable to open file";
return 0;
}


As well as giving you the data in a std::vector<char> directly, this is also exception safe - using new directly, if an exception got thrown before your delete [] memblock line, you'd get a memory leak.

Share this post


Link to post
Share on other sites
file.close() is also redundant, since 'file' is auto-allocated. Some additional error checking may also be useful.

int main () {

ifstream file ("example.txt", ios::in|ios::binary|ios::ate);

if (!file.is_open()) {
cout << "Unable to open file";
return 1;
}

file.seekg (0, ios::end);
size = file.tellg();
if (size == -1) {
cout << "Could not determine file size";
return 1;
}

std::vector<char> memblock(size);
file.seekg (0, ios::beg);
file.read(&(memblock[0]),size);

if (file.fail()) {
cout << "Error reading file contents";
return 1;
}

cout << "the complete file content is in memory";
return 0;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by iansane
Can anyone tell me how to do this? I tried vector.push_back(memblock) and it seems to be working but I get an error at run time saying the program needs to close. I don't think I'm understanding how it works. Do I need to read into another variable to use with push_back?


You never (unless I'm missing a weird corner case; not thinking about it very hard right now) *need* to use a temporary variable in order to call a function. The arguments for a function call are expressions. Anyway, such problems would be caught by the compiler.

.push_back() puts one element onto the end of a vector. If the compiler lets you .push_back() the memblock, then you must have a vector of pointers to char. That is not what you want; you want a vector of char, because the vector will itself serve as the buffer directly.

The way you make use of the vector's memory management - at least, that way that's analogous to the current approach - is to first make sure the vector is big enough to hold all the incoming data, and then read into its buffer, directly. The point of using a vector, rather than a deque or list, for this is that the vector allocates a single chunk of memory that you can read into. The other posters have shown how this is done in detail. :)

Share this post


Link to post
Share on other sites
Thanks all of you for your detailed explanations and the error checking tips.

I rewrote the whole program according to some advice from another forum and what I get now is not binary.

What I get for a text file is the actual text (not binary), and for a jpg, I get the same as what I get if I open a jpg with notepad.

example:

ÿØÿà JFIF H H ÿá Exif MM * ÿÛ C ÿÛ CÿÀ à€" ÿÄ
ÿÄ f

!1AQaÁð$q‘¡±á4Ñ%Dñ 5Td‚&ERt¢6U„ÂÒâ"#3BCbe¤´FSVWc’”ÄÔ'2suv…•–7GfµÿÄ ÿÄ D !1AQaq‘¡ð±ÁÑáñ"$2BRb‚4Dr’²ÂÒ¢â#3Ã%ÿÚ ? 一…3€( ] ¼'8™Âpð0™Àp!7€( ]0›Âpð ¼'8 ¼@P&ðœ8át&ð œ „œ@ „œ@ „œ@ ˜Mà pœ( “€( 8€ 8€œ@ !' € '
èJ …„ (



I'll try it your way now and post if I have trouble with it. But I should clarify what I'm trying to do here.

I am trying to get the 1's and 0's that make the file. (totally unencoded binary). Isn't that what I need if I want to encrypt, decrypt, or even try to hide a file in a file? I'm sure there is a lot that I am missing since I don't know a lot about encoding, (did some 64 bit encoding on paper with a chart once) , so am I going about this the right way?

Share this post


Link to post
Share on other sites
Tried it this way and got the same thing.

Undecypherable symbols for jpg

actual text for txt file. If I type "bla bla bla" in a test.txt file and open it, the out put is "bla bla bla", not binary.

Any ideas?

Thanks

Share this post


Link to post
Share on other sites
A binary file is a list of numbers.

A text file is also a list of numbers.

If you input binary data, then print it to the screen using a system that interprets 8 bit (or whatever) values as ASCII (or whatever) values, you will get some kind of text, regardless of whether those numbers are actually representing text or not.

What did you expect to see when you printed your "binary" data? A list of noughts and ones?

If you want to see them as decimal numbers rather than their character representations, you need to do something like this:


for(size_t i=0;i<memblock.size();++i) std::cout << int(memblock) << std::endl;


Just trying to print the data as a character array will cause cout to treat it as a character array.

You really need to understand that the only difference between a binary file and a text file is the way the data is intepreted by the application reading it in. On the hard drive, a file is a file is a file and is a list of numbers that are meaningless without a context.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!