By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,786 Members | 1,142 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,786 IT Pros & Developers. It's quick & easy.

Convert from std::string to unsigned char*

P: n/a
Im very much a newbie but perhaps somehone can help me. Ive been
searching for a way to convert a std::string to a unsigned char*

The situation is I have a function that wants a unsigned char* and I
want to give it a std::string

no matching function for call to `MD5::update(std::string&, size_t)'
candidates are: void MD5::update(unsigned char*, unsigned int)

void PrintMD5(string str){
MD5 context;

context.update(str, str.size());
context.finalize();

cout << "MD5: " << context << endl;

return;
}

I hope someone can help me solve this delema.

Aug 21 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
sposes wrote:
context.update(str, str.size());
context.update(str.c_str(), str.size());

Please read a good chunk of a C++ tutorial before resuming coding. It might
not have covered c_str(), yet you would still pick enough tips to figure the
c_str() out for yourself!

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Aug 21 '06 #2

P: n/a
Phlip wrote:
sposes wrote:

> context.update(str, str.size());


context.update(str.c_str(), str.size());
That won't work, str.c_str() returns const char*, the OP's function
requires unsigned char*.

Passing a std::string might be unsafe, considering the function doesn't
take a const pointer as a parameter.
Please read a good chunk of a C++ tutorial before resuming coding. It might
not have covered c_str(), yet you would still pick enough tips to figure the
c_str() out for yourself!
No comment....

--
Ian Collins.
Aug 21 '06 #3

P: n/a
<sp****@gmail.comwrote in message
news:11**********************@i3g2000cwc.googlegro ups.com...
Im very much a newbie but perhaps somehone can help me. Ive been
searching for a way to convert a std::string to a unsigned char*

The situation is I have a function that wants a unsigned char* and I
want to give it a std::string

no matching function for call to `MD5::update(std::string&, size_t)'
candidates are: void MD5::update(unsigned char*, unsigned int)

void PrintMD5(string str){
MD5 context;

context.update(str, str.size());
context.finalize();

cout << "MD5: " << context << endl;

return;
}

I hope someone can help me solve this delema.
std::string.c_str() will return a const char *. Notice very carefully this
is const. That means that the contents can't be changed through this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
strcpy( TempString, str.c_str() );
context.update( TempString, strlen( TempString ) );
....

If you know for a total fact that update will not be changing the contents
of the string, and you have to be absolutely sure of this, you can cast away
the const.

context.update( const_cast< char* >( str.c_str() ), str.size() );

I do this for one library I use where the designer is not using const
correctness.
Aug 21 '06 #4

P: n/a
Jim Langston schrieb:
<sp****@gmail.comwrote in message
news:11**********************@i3g2000cwc.googlegro ups.com...
>Im very much a newbie but perhaps somehone can help me. Ive been
searching for a way to convert a std::string to a unsigned char*

The situation is I have a function that wants a unsigned char* and I
want to give it a std::string

no matching function for call to `MD5::update(std::string&, size_t)'
candidates are: void MD5::update(unsigned char*, unsigned int)

void PrintMD5(string str){
MD5 context;

context.update(str, str.size());
context.finalize();

cout << "MD5: " << context << endl;

return;
}

I hope someone can help me solve this delema.

std::string.c_str() will return a const char *. Notice very carefully this
is const. That means that the contents can't be changed through this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
Why 'size * 2' ??
strcpy( TempString, str.c_str() );
You'd need a cast here.
context.update( TempString, strlen( TempString ) );
...
Why not use a std::vector ?

std::vector<unsigned chartempV(str.begin(), str.end());
context.update(&tempV[0], tempV.size());

If you know for a total fact that update will not be changing the contents
of the string, and you have to be absolutely sure of this, you can cast away
the const.

context.update( const_cast< char* >( str.c_str() ), str.size() );

I do this for one library I use where the designer is not using const
correctness.
/S
--
Stefan Naewe
stefan_DOT_naewe_AT_atlas_DOT_de
Aug 21 '06 #5

P: n/a

"Stefan Naewe" <pl****@nospam.netwrote in message
news:6e***********@news01.atlas.de...
Jim Langston schrieb:
><sp****@gmail.comwrote in message
news:11**********************@i3g2000cwc.googlegr oups.com...
>>Im very much a newbie but perhaps somehone can help me. Ive been
searching for a way to convert a std::string to a unsigned char*

The situation is I have a function that wants a unsigned char* and I
want to give it a std::string

no matching function for call to `MD5::update(std::string&, size_t)'
candidates are: void MD5::update(unsigned char*, unsigned int)

void PrintMD5(string str){
MD5 context;

context.update(str, str.size());
context.finalize();

cout << "MD5: " << context << endl;

return;
}

I hope someone can help me solve this delema.

std::string.c_str() will return a const char *. Notice very carefully
this
is const. That means that the contents can't be changed through this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char
array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];

Why 'size * 2' ??
It is unknown how much the update function is going to change the string.
*2 was a guess at worst case scenario. It may need to be *100, or simply a
fixed limit, unknown without knowing what update is going to do.
>strcpy( TempString, str.c_str() );

You'd need a cast here.
Hmm.. definition I have for strcpy is:
char *strcpy( char *strDestination, const char *strSource );

The only thing I see different is TempString is unsigned where
strDestination is signed. Won't it only give a warning for that?
>context.update( TempString, strlen( TempString ) );
...

Why not use a std::vector ?

std::vector<unsigned chartempV(str.begin(), str.end());
context.update(&tempV[0], tempV.size());
Well, it is presumed that update will change the content (otherwise they can
just use the const_cast) so it's also presumed that the size of the string
will be different. As such, you haven't allocated enough space in your
vector so are going to need another call to allocate more space. Since the
main purpose of using std::vector and std::string over char arrays is
dynamic growth, and because we don't have dynamic growth in the temp object,
might as well just use the char array since we have to allocate the size
anyway. Using std::vector gains us nothing, unless the size is fixed.
>If you know for a total fact that update will not be changing the
contents
of the string, and you have to be absolutely sure of this, you can cast
away
the const.

context.update( const_cast< char* >( str.c_str() ), str.size() );

I do this for one library I use where the designer is not using const
correctness.

Aug 21 '06 #6

P: n/a
Jim Langston schrieb:
"Stefan Naewe" <pl****@nospam.netwrote in message
news:6e***********@news01.atlas.de...
>Jim Langston schrieb:
>><sp****@gmail.comwrote in message
news:11**********************@i3g2000cwc.googleg roups.com...
Im very much a newbie but perhaps somehone can help me. Ive been
searching for a way to convert a std::string to a unsigned char*

The situation is I have a function that wants a unsigned char* and I
want to give it a std::string

no matching function for call to `MD5::update(std::string&, size_t)'
candidates are: void MD5::update(unsigned char*, unsigned int)

void PrintMD5(string str){
MD5 context;

context.update(str, str.size());
context.finalize();

cout << "MD5: " << context << endl;

return;
}

I hope someone can help me solve this delema.
std::string.c_str() will return a const char *. Notice very carefully
this
is const. That means that the contents can't be changed through this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char
array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
Why 'size * 2' ??

It is unknown how much the update function is going to change the string.
*2 was a guess at worst case scenario. It may need to be *100, or simply a
fixed limit, unknown without knowing what update is going to do.
True.
Who knows without seeing the doc for MD5::update()
>>strcpy( TempString, str.c_str() );
You'd need a cast here.

Hmm.. definition I have for strcpy is:
char *strcpy( char *strDestination, const char *strSource );

The only thing I see different is TempString is unsigned where
strDestination is signed. Won't it only give a warning for that?
My g++ gives me:

"error: invalid conversion from 'unsigned char*' to 'char*' "
>>context.update( TempString, strlen( TempString ) );
...
Why not use a std::vector ?

std::vector<unsigned chartempV(str.begin(), str.end());
context.update(&tempV[0], tempV.size());

Well, it is presumed that update will change the content (otherwise they can
just use the const_cast) so it's also presumed that the size of the string
will be different. As such, you haven't allocated enough space in your
vector so are going to need another call to allocate more space. Since the
main purpose of using std::vector and std::string over char arrays is
dynamic growth, and because we don't have dynamic growth in the temp object,
might as well just use the char array since we have to allocate the size
anyway. Using std::vector gains us nothing, unless the size is fixed.
Even if MD5::update() changed the passed string using, a std::vector would
IMHO be better because:
- no way to forget to delete[]
- no need to cast
- no bad feeling in the neck because std::strings' memory is not guaranteed
to be contiguous (at least not yet IIRC)

/S
--
Stefan Naewe
stefan_DOT_naewe_AT_atlas_DOT_de
Aug 21 '06 #7

P: n/a

"Jim Langston" <ta*******@rocketmail.comwrote in message
news:7E*************@newsfe02.lga...
std::string.c_str() will return a const char *. Notice very carefully
this is const. That means that the contents can't be changed through
this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
strcpy( TempString, str.c_str() );
context.update( TempString, strlen( TempString ) );
...
It's a bad idea to simply "guess" what a function will do with a string, and
how long an array you might need. Such guesses are bound to either 1) fail
miserably at some point, or 2) use up memory needlessly. And nobody's going
to understand why you've chosen to arbitrarily double the size.

I doubt that update() is updating the string. More likely, it's updating
the "context" object. If it _is_ updating the string, then it should be
doing the allocation as well. It's poorly designed if you tell it how much
data it _can_ use, but it decides how much it _needs_ to use. What should
it do if it needs more than you gave it?

-Howard

Aug 21 '06 #8

P: n/a
Im still reading the replys and will let you know what hapens soon.
Howard wrote:
"Jim Langston" <ta*******@rocketmail.comwrote in message
news:7E*************@newsfe02.lga...
std::string.c_str() will return a const char *. Notice very carefully
this is const. That means that the contents can't be changed through
this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char array
to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
strcpy( TempString, str.c_str() );
context.update( TempString, strlen( TempString ) );
...

It's a bad idea to simply "guess" what a function will do with a string, and
how long an array you might need. Such guesses are bound to either 1) fail
miserably at some point, or 2) use up memory needlessly. And nobody's going
to understand why you've chosen to arbitrarily double the size.

I doubt that update() is updating the string. More likely, it's updating
the "context" object. If it _is_ updating the string, then it should be
doing the allocation as well. It's poorly designed if you tell it how much
data it _can_ use, but it decides how much it _needs_ to use. What should
it do if it needs more than you gave it?

-Howard
Aug 21 '06 #9

P: n/a
sp****@gmail.com wrote:
Im still reading the replys and will let you know what hapens soon.

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html>

Brian

Aug 21 '06 #10

P: n/a

"Howard" <al*****@hotmail.comwrote in message
news:kV********************@bgtnsc04-news.ops.worldnet.att.net...
>
"Jim Langston" <ta*******@rocketmail.comwrote in message
news:7E*************@newsfe02.lga...
>std::string.c_str() will return a const char *. Notice very carefully
this is const. That means that the contents can't be changed through
this.

If the
context.update( unsigned char*, unsigned int )
is going to change the contents of the char *, which I highly expect it
will, you can't use this.

My solution in these cases is to actually copy the c_str() to a char
array to copy it back.

unsigned char* TempString = new unsigned char[ str.size() * 2 ];
strcpy( TempString, str.c_str() );
context.update( TempString, strlen( TempString ) );
...

It's a bad idea to simply "guess" what a function will do with a string,
and how long an array you might need. Such guesses are bound to either 1)
fail miserably at some point, or 2) use up memory needlessly. And
nobody's going to understand why you've chosen to arbitrarily double the
size.
I agree. I had planned on explaining why I was using str.size() * 2 instead
of simply str.size() but had forgot. My bad.
I doubt that update() is updating the string. More likely, it's updating
the "context" object. If it _is_ updating the string, then it should be
doing the allocation as well. It's poorly designed if you tell it how
much data it _can_ use, but it decides how much it _needs_ to use. What
should it do if it needs more than you gave it?
I doubt it highly too. Most likely the method is just not const
correctness, and if the OP has the source to the class he should fix it to
be const unsigned char*.

I use a library where I don't have the source (it's a .dll) but only the
interface so can't mess with the signatures by fixing the const correctness
myself and in those cases I use a const_cast because I know for a fact that
the function is not going to change the string.

Aug 21 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.