string and char elements - c++

I have an unsigned char* c that contains the element 0x1c. How can I add it into an std::vector<unsigned char>vect? I am working in c++.
std::vector<unsigned char>vect; //the vect dimention is dynamic
std::string at="0x1c";
c=(unsigned char*)(at.c_str());
vect[1]=c //error? why?

//The vect dimension is dynamic ONLY if you call push_back
std::vector <std::string> vect;
std::string at="0x1c";
vect.push_back(at);
If you are using C++, use std::string. The above code will copy your "0x1c" string into the vector.
If you try to do
vect[0] = c;
Without first expanding the vector with
vect.resize(1);
You will get segmentation fault because operator[] doesn't expand the the vector dynamically. The initial size of a vector is 0 btw.
UPDATE: According to the OP's comment, here is what he would want: copying a unsigned char * to a std::vector (i.e.copying a C array to a C++ vector)
std::string at = "0x1c";
unsigned char * c = (unsigned char*)(at.c_str());
int string_size = at.size();
std::vector <unsigned char> vect;
// Option 1: Resize the vector before hand and then copy
vect.resize(string_size);
std::copy(c, c+string_size, vect.begin());
// Option 2: You can also do assign
vect.assign(c, c+string_size);

c is an unsigned char*. vect is a std::vector<unsigned char>, so it contains unsigned char values. The assignment will fail, as operator [] on std::vector<unsigned char> expects an unsigned char, not a unsigned char *.

You have a hex representation of a character in a string, and you want the character?
easiest:
unsigned char c;
istringstream str(at);
str >> hex >> c; // force the stream to read in as hex
vect.push_back(c);
(I think that should work, have not tested it)
I just reread your question again, this line:
I have an unsigned char* c that
contains the element 0x1c
Does this mean that actually your unsigned char* looks like this:
unsigned char c[] = {0x1c}; // i.e. contains 1 byte at position 0 with the value 0x1c?
or my assumption above...
to print the vector out to cout, use a simple for loop, or if you are feeling brave
std::cout << std::ios_base::hex;
std::copy(vect.begin(), vect.end(), std::ostream_iterator<unsigned char>(std::cout, " "));
std::cout << std::endl;
this will print the hex representations of each of the unsigned char values in the vector separated by a space.

Related

Convert int to char then push back to vector

i'm having an issue converting an int into a char. Code looks like :
int main {
int i = 10;
char c[80];
std::vector<char> data;
sprintf(i,"%d",c);
data.push_back(c)
}
But I keep getting a invalid conversion from char* to std::vector ... error. Is there an easier way to convert an integer into a character and then store it inside a vector that holds chars? Because of an earlier task I need to first bring in the value as an int and I need to bring that integer 10 into the vector as '10'.
For starters it seems there is a typo
sprintf(text,"%d",f);
You nean
sprintf( c ,"%d", i );
The value type of this vector
std::vector<char> data;
is char. So in the member function push you have to supply an expression that has the type char. However in this call
data.push_back(c);
you supplied an object of an array type
char c[80];
If you want to store in the vector a character representation of a number as separate characters then you can write for example
size_t n = strlen( c );
data.reserve( n );
data.assign( c, c + n );
Or you could declare the vector initializing it by the representation of the number like
std::vector<char> data( c, c + n );
If you want to store the whole number as one element of the vector then you should declare the vector like
std::vector<std::string> data( 1, std::to_string( i ) );

Char array with non-constant size while initialiazing

I need in C++ char array that is while initialiazing non-constant size. Size have to be non-constant cause it's generated from function and can't be used vector cause this char array will be used for reading and writing to files. Example:
int i = functionToGetvalue();
unsigned char ch[i];
file1 >> ch;
file2 << ch;
The premise is wrong. While there are reasons to prefer c-style arrays (or std::array) over vectors, yours is certainly not the one. You can certainly use std::vector to read and write to the file, since it is guaranteed to be contiguous in memory.
Example:
std::vector<char> vec;
vec.resize(255);
ssize_t sz = read(fd, vec.data(), vec.size());
In your original example, you are using formatted streams I/O, and in this case, std::string is a best tool:
std::string str;
file1 >> str; // reads up to the next white space into str

Passing string to function which accepts pointer to char

I've been working with OpenSSL library in C for a long time, but now I need to migrate to C++. OpenSSL's docs describe MD5 function like this.
unsigned char *MD5(const unsigned char *d, unsigned long n,
unsigned char *md);
I want to pass variable of type string to that function, but it accepts only char *.
Is it possible to pass string to parameter of type char * directly in C++? (I don't want to use extra manipulation with variable of type string)
You could use the c_str member function that std::string sports. Example
std::string data;
// load data somehow
unsigned char md[16] = { };
unsigned char *ret = MD5(reinterpret_cast<const unsigned char*>(data.c_str()),
data.size(),
md);
If you want to do away with the ugly cast operator, define a string class that holds unsigned chars instead of chars and use that.
typedef std::basic_string<unsigned char> ustring;
ustring data;
unsigned char *ret = MD5(data.c_str(), data.size(), md);
just a little note, which may save you a headache later on. MD5 takes an unsigned char pointer as a parameter. This is a clue that it's actually not a string, but a pointer to bytes.
In your program if you start storing byte vectors in a std::string, you're eventually going to initialise a string with a byte vector containing a zero, which opens the possibility of a bug that's difficult to detect down the line.
It is safer to store all your byte vectors in a std::vector<unsigned char> (or std::vector<uint8_t> because this forces safe initialisation.
std::vector<unsigned char> plaintext;
// initialise plaintext here
std::vector<unsigned char> my_hash(16);
MD5(plaintext.data(), plaintext.size(), &my_hash[0]);

c++: Storing an adress as string

I'm trying to store the address of a pointer as a string. In other words, I want to insert the content of the bytes that make up the address into a char vector.
What is the best way of doing this?
I need a fully portable method, including for 64 bit system.
To get an array (or vector, if you prefer that) of the actual bytes of the address, this should do the trick:
int foo = 10;
int* bar = &foo;
// Interpret pointer as array of bytes
unsigned char const* b = reinterpret_cast<unsigned char const*>(&bar);
// Copy that array into a std::array
std::array<unsigned char, sizeof(void*)> bytes;
std::copy(b, b + sizeof(void*), bytes.begin());
To get an array containing the hexadecimal representation split up into single characters (whatever sense that makes), I'd use a stringstream - as some of the others already suggested. You can also use snprintf to get a string representation of the address, but that's more the C-style way.
// Turn pointer into string
std::stringstream ss;
ss << bar;
std::string s = ss.str();
// Copy character-wise into a std::array (1 byte = 2 characters)
std::array<char, sizeof(void*) * 2> hex;
std::copy(s.begin(), s.end(), hex.begin());
The simplest way is to do
char buf[sizeof(void*) * 2 + 3];
snprintf(buf, sizeof(buf), "%p", /* the address here */ );
std::string serialized (std::to_string ((intptr_t) ptr));
C++ way to dos this would be to use string streams
#include <string>
#include <sstream>
int main()
{
MyType object;
std::stringstream ss;
std::string result;
ss << &object; // puts the formatted address of object into the stream
result = ss.str(); // gets the stream as a std::string
return 0;
}
void storeAddr(vector<string>& v,void *ptr)
{
stringstream s;
s << (void*)ptr ;
v.push_back(s.str());
}

const char * to vector<unsigned char> Initalisation

I understand that using vector is a good way to store binary data when using C++ and the STL. However for my unit tests I'd like to initalise the vector using a const char* C string variable.
I'm attempting to use a variant of the code found here - Converting (void*) to std::vector<unsigned char> - to do this:
const char* testdata = "the quick brown fox jumps over the lazy dog.";
unsigned char* buffer = (unsigned char*)testdata;
typedef vector<unsigned char> bufferType;
bufferType::size_type size = strlen((const char*)buffer);
bufferType vec(buffer, size);
However the VC++ compiler is not happy with the line initialising the vector, stating:
error C2664: 'std::vector<_Ty>::vector(unsigned int,const _Ty &)' : cannot convert parameter 1 from 'char *' to 'unsigned int'
I appreciate the extreme n00bity of this question and am fully prepared for much criticism on the code above :)
Thanks in advance,
Chris
It should be
bufferType vec(buffer, buffer + size);
not
bufferType vec(buffer, size);
std::transform is useful for just this sort of problem. You can use it to "transform" one piece of data at a time. See documentation here:
http://www.cplusplus.com/reference/algorithm/transform/
The following code works in VS2010. (I created a std::string from your const char* array, but you could probably avoid that if you really wanted to.)
#include <algorithm>
#include <vector>
int main(int, char*[])
{
// Initial test data
const char* testdata = "the quick brown fox jumps over the lazy dog.";
// Transform from 'const char*' to 'vector<unsigned char>'
std::string input(testdata);
std::vector<unsigned char> output(input.length());
std::transform(input.begin(), input.end(), output.begin(),
[](char c)
{
return static_cast<unsigned char>(c);
});
// Use the transformed data in 'output'...
return 0;
}
Here is what worked for me:
// Fetch data into vector
std::vector<char> buffer = <myMethod>.getdata();
// Get a char pointer to the data in the vector
char* buf = buffer.data();
// cast from char pointer to unsigned char pointer
unsigned char* membuf = reinterpret_cast<unsigned char*>(buf);
// now convert to vector<unsigned char> buffer
std::vector<unsigned char> vec(membuf, membuf + buffer.size());
// display vector<unsigned char>
CUtils::<myMethodToShowDataBlock>(vec);
What you intended to do seems to be something like:
buffertype vec(testdata, next(testdata, strlen(testdata)));
There is no need for the intermediate buffer variable. The conversion from char to unsigned char will happen implicitly.
Note that this does not grab the terminating '\0' character from testdata. So if you wanted to be able to do something like: cout << vec.data() you wouldn't be able to. If you want that you could do: buffertype vec(testdata, next(testdata, strlen(testdata) + 1)) or you may just want to consider doing:
basic_string<unsigned char> vec(testdata, next(testdata, strlen(testdata)));
Which will preserve a hidden '\0'. Because this is not a string you won't be able to do, cout << vec but cout << vec.data() will work. I've created a Live Example of each of these.