tags:

views:

1288

answers:

4

Hi can any body tell me how to conver const char* to char*?

get_error_from_header(void *ptr, size_t size, size_t nmemb, void *data) {
    ErrorMsg *error = (ErrorMsg *)data;
    char* err = strstr((const char *)ptr,"550"); //error  cannot convert const char** to char*
    if(NULL != err) {
        strncpy(error->data,(char*)ptr,LENGTH_ERROR_MESSAGE-1);
        error->data[LENGTH_ERROR_MESSAGE-1] = '\0';
        error->ret = true;
    }
    return size*nmemb;
}
+5  A: 

Can't you just do:

char* err = strstr((char *)ptr,"550");

The error is because if you pass in a const char* to strstr you get one out (because of the overload).

Matthew Flaschen
Or const char * for both.
Steve Jessop
True. It depends what he's ultimately going to do with it (currently nothing except check for NULL)
Matthew Flaschen
Nice its working now
Cute
+1  A: 

You don't appear to use err in the rest of that function, so why bother creating it?

if (NULL != strstr((const char *)ptr, "550"))
{

If you do need it, will you really need to modify whatever it points to? If not, then declare it as const also:

const char* err = strstr((const char *)ptr, "550");

Finally, as casts are such nasty things, it is best to use a specific modern-style cast for the operation you want to perform. In this case:

if (NULL != strstr(reinterpret_cast<const char *>(ptr), "550"))
{
Daniel Earwicker
A: 

Well is ptr (which you passed in as void*) actually const or not? (In other words, is the memory under your control?) If it's not, then cast it to char* instead of const char* when calling strstr. If it is, however, you'll get a const char* out (pointing to a location inside of the string pointed to by ptr), and will then need to strncpy out to another string which you are responsible for managing.

Yuliy
+3  A: 

There are a few things I don't understand here. I see that this is tagged for C++/CLI, but what I describe below should be the same as Standard C++.

Doesn't compile

The code you give doesn't compile; get_error_from_header does not specify a return type. In my experiments I made the return type size_t.

Signature of C++ strstr()

The signature for strstr() in the standard C library is:

char *
strstr(const char *s1, const char *s2);

but the signature for strstr() in the C++ library, depending on the overload, is one of:

const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );

I would choose the first overload, because you don't want to modify the string, you only want to read it. Therefore you can change your code to:

const char* err = strstr((const char *)ptr, "550");
if (err != NULL) {
    ...
}

Also, I'm assuming your comment reporting the error:

//error  cannot convert const char** to char*

is a typo: there's no const char** to be seen.

Assignment to err unnecessary

As is pointed out in a previous answer, the use of err to store the result of strstr is unnecessary if all it's used for is checking NULL. Therefore you could use:

if (strstr((const char *)ptr, "550") != NULL) {
    ...
}

Use of reinterpret_cast<> encouraged

As is pointed out in another answer you should be using reinterpret_cast<> instead of C-style casts:

if (strstr(reinterpret_cast<const char *>(ptr), "550") != NULL) {
    ...
}

Use of const_cast<> to strip const

Given the example in the question, I don't see where this is necessary, but if you had a variable that you need to strip of const-ness, you should use the const_cast<> operator. As in:

const char * p1;
char * p2;

p2 = const_cast<char *>(p1);

As is pointed out in a comment, the reason to use const_cast<> operator is so that the author's intention is clear, and also to make it easy to search for the use of const_cast<>; usually stripping const is the source of bugs or a design flaw.

Jared Oberhaus
I think "const char** to char*" was just a typo. And I agree that there's no point in creating a variable if it's never used. So I basically agree with your "Unnecessary const-ing" code, except I'm not clear on the benefit of reinterpret_cast.
Matthew Flaschen
You're quoting the signature of strtr() from C, not C++.
MSalters
One more reason to use const_cast is that it is easier to search. By simply searching in the code for "const_cast" keyword you can find all the places where the developer changed the constness. This is good because constness change usually is a source for problems/bugs.
Cătălin Pitiș
The benefit of reinterpret_cast is that the void *ptr won't work as a char * parameter (const or not), depending on the compiler/settings. Also, in C++ using the casting operators such as reinterpret_cast instead of C-style cast gives you the benefit of knowing what the original author's intent was in casting, and being able to search for such casts.
Jared Oberhaus
@MSalters mentions that I'm quoting the signature of strstr() from C, not C++; what is the signature of the C++ strstr()? Is this a C++/CLI difference, that strstr() has a different signature under C++ than C?
Jared Oberhaus
C strstr has one signature (http://www.opengroup.org/onlinepubs/000095399/functions/strstr.html), char *strstr(const char *s1, const char *s2); C++ has two (http://www.cplusplus.com/reference/clibrary/cstring/strstr/), const char * strstr ( const char * str1, const char * str2 ); and char * strstr ( char * str1, const char * str2 ); Note that neither of these matches the C signature.
Matthew Flaschen
Thanks @Matthew Flaschen, I'll update my answer.
Jared Oberhaus