Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Convert from std::string to unsigned char*

Reply
Thread Tools

Convert from std::string to unsigned char*

 
 
sposes@gmail.com
Guest
Posts: n/a
 
      08-21-2006
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.

 
Reply With Quote
 
 
 
 
Phlip
Guest
Posts: n/a
 
      08-21-2006
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!!!


 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      08-21-2006
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.
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      08-21-2006
<> wrote in message
news: 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.


 
Reply With Quote
 
Stefan Naewe
Guest
Posts: n/a
 
      08-21-2006
Jim Langston schrieb:
> <> wrote in message
> news: 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 char> tempV(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
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      08-21-2006

"Stefan Naewe" <> wrote in message
news:6eobce-...
> Jim Langston schrieb:
>> <> wrote in message
>> news: 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' ??


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 char> tempV(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.



 
Reply With Quote
 
Stefan Naewe
Guest
Posts: n/a
 
      08-21-2006
Jim Langston schrieb:
> "Stefan Naewe" <> wrote in message
> news:6eobce-...
>> Jim Langston schrieb:
>>> <> wrote in message
>>> news: 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' ??

>
> 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 char> tempV(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
 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      08-21-2006

"Jim Langston" <> wrote in message
news:7EaGg.427$...

> 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



 
Reply With Quote
 
sposes@gmail.com
Guest
Posts: n/a
 
      08-21-2006
Im still reading the replys and will let you know what hapens soon.


Howard wrote:
> "Jim Langston" <> wrote in message
> news:7EaGg.427$...
>
> > 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


 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      08-21-2006
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
unsigned long to unsigned char ashtonn@gmail.com Python 1 06-01-2005 07:00 PM
comparing unsigned long and unsigned int sridhar C Programming 6 11-03-2004 03:52 AM
unsigned int const does not match const unsigned int Timo Freiberger C++ 3 10-30-2004 07:02 PM
Assigning unsigned long to unsigned long long George Marsaglia C Programming 1 07-08-2003 05:16 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57