19

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(err) {
        strncpy(error->data,(char*)ptr,LENGTH_ERROR_MESSAGE-1);
        error->data[LENGTH_ERROR_MESSAGE-1] = '\0';
        error->ret = true;
    }
    return size*nmemb;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Cute
  • 13,643
  • 36
  • 96
  • 112

6 Answers6

17

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
  • 14,547
  • 4
  • 56
  • 55
  • 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 May 07 '09 at 08:10
  • 1
    You're quoting the signature of strtr() from C, not C++. – MSalters May 07 '09 at 08:11
  • 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ș May 07 '09 at 09:22
  • 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 May 07 '09 at 15:06
  • @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 May 07 '09 at 15:08
  • 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 May 07 '09 at 16:02
  • Thanks for p2 = const_cast(p1); that's exactly what I was looking for. – Katu Oct 10 '14 at 07:50
  • You did mention that the use of reinterpret_cast<> is encouraged, could you help on understand why if at all that is a bad choice as compared to const_cast<>. – Krishna Oza Nov 26 '14 at 05:29
9

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
  • 114,894
  • 38
  • 205
  • 284
8

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
  • 278,309
  • 50
  • 514
  • 539
5

//try this instead:

const char* mstr="";
char* str=const_cast<char*>(mstr);
hmehdi
  • 101
  • 1
  • 5
0

According to my deep research I have found numerous forums that have no direct solution or a reference answer to this question, I then delve into the GCC online documentation giving a brief read for their compiler properly docs and this is what I can provide.

In GNU C, pointers to arrays with qualifiers work similar to pointers to other qualified types. For example, a value of type int ()[5] can be used to initialize a variable of type const int ()[5]. These types however aren't compatible in ISO C because the const qualifier is formally attached to the element type of the array and not the array itself.

This description might be better understood if we take this

extern void
transpose (int N, int M, double out[M][N], const double in[N][M]);
double x[3][2];
double y[2][3];
…
transpose(3, 2, y, x);

Observing the above is that if you had an

s1=createStudent(s1, 123, "Poli");
s2=createStudent(s2, 456, "Rola);

Whereas the const char[5] for both "Poli" and "Rola" have correlation to a char a[]. It is strictly not permitted as each element has the qualifier attached and not the entire array as a const.

KairoSkey
  • 1
  • 3
0

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
  • 17,381
  • 6
  • 41
  • 47