Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL's String eqivalent for Binary Data

I am writing a C++ application and I was wondering what the C++ conventional way of storing a byte array in memory.

Is there something like a string, except specifically made for binary data.

Right now I am using a *unsigned char** array to store the data, but something more STL/C++ like would be better.

like image 520
The Unknown Avatar asked May 07 '09 23:05

The Unknown


People also ask

Can we write a string to binary file?

char* buffer = (char*) malloc(sizeof(string)); ifstream infile("myfile. txt", ifstream::binary); infile. read(buffer, sizeof (prueba)); std::string* elem = (string*) buffer; cout << *elem; infile. close();

Is std::string in C?

The std::string class manages the underlying storage for you, storing your strings in a contiguous manner. You can get access to this underlying buffer using the c_str() member function, which will return a pointer to null-terminated char array. This allows std::string to interoperate with C-string APIs.

What are binary strings?

A binary string is a sequence of bytes. Unlike a character string which usually contains text data, a binary string is used to hold non-traditional data such as pictures. The length of a binary string is the number of bytes in the sequence.


4 Answers

I'd use std::vector<unsigned char>. Most operations you need can be done using the STL with iterator ranges. Also, remember that if you really need the raw data &v[0] is guaranteed to give a pointer to the underlying array.

like image 145
CAdaker Avatar answered Oct 27 '22 21:10

CAdaker


You can use std::string also for binary data. The length of the data in std::string is stored explicitly and not determined by null-termination, so null-bytes don't have special meaning in a std::string.

std::string is often more convenient than std::vector<char> because it provides many methods that are useful to work with binary data but not provided by vector. To parse/create binary data it is useful to have things like substr(), overloads for + and std::stringstream at your disposal. On vectors the algorithms from <algorithm> can be used to achieve the same effects, but it's more clumsy than the string methods. If you just act on "sequences of characters", std::string gives you the methods you usually want, even if these sequences happen to contain "binary" data.

like image 34
sth Avatar answered Oct 27 '22 23:10

sth


You should use std::vector<unsigned char> or std::vector<uint8_t> (if you have a modern stdint.h header). There's nothing wrong with using unsigned char[] or uint8_t[] if you are working with fixed size buffers. Where std::vector really shines is when you need to grow or append to your buffers frequently. STL iterators have the same semantics as pointers, so STL algorithms will work equally well with std::vector and plain old arrays.

And as CAdaker pointed out, the expression &v[0] is guaranteed to give you the underlying pointer to the vector's buffer (and it's guaranteed to be one contiguous block of memory). This guarantee was added in an addendum to the C++ standard.

Personally, I'd avoid using std::string to manipulate arbitrary byte buffers, since I think it's potentially confusing, but it's not an unheard of practice.

like image 21
Don McCaughey Avatar answered Oct 27 '22 21:10

Don McCaughey


There are multiple solutions but the closest one (I feel) is the std::vector<std::byte>> because it expresses the intent directly in code.

From : https://en.cppreference.com/w/cpp/types/byte

std::byte is a distinct type that implements the concept of byte as specified in the C++ language definition.

Like char and unsigned char, it can be used to access raw memory occupied by other objects (object representation), but unlike those types, it is not a character type and is not an arithmetic type. A byte is only a collection of bits, and the only operators defined for it are the bitwise ones.

like image 1
Sitesh Avatar answered Oct 27 '22 22:10

Sitesh