3

I'm trying to use the function with the following declaration: extern int stem(struct stemmer * z, char * b, int k)1

I'm trying to pass a C++ string to it, so I thought I'd use the c_str() function. It returns const char *. When I try to pass it to the stem() function, I get this error: error: invalid conversion from 'const char*' to 'char*' [-fpermissive].

How can I store the result of c_str() such that I can use it with the stem function?

Here is the code I'm running:

    struct stemmer * z = create_stemmer();
    char * b = s.c_str();
    int res = stem(z, b, s.length()); //this doesn't work
    free_stemmer(z);
    return s.substr(0,res);
Wolf
  • 9,679
  • 7
  • 62
  • 108
muttley91
  • 12,278
  • 33
  • 106
  • 160

6 Answers6

8

The problem you are having is that c_str() returns a buffer that can not be modified (const), while stem() may modify the buffer you pass in (not const). You should make a copy of the result of c_str() to get a modifiable buffer.

The page http://www.cplusplus.com/reference/string/string/c_str/ has more information on the C++ 98 and 11 versions. They suggest replacing char * b = s.c_str(); with the following:

char * b = new char [s.length()+1];
std::strcpy (b, s.c_str());
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
2

You shouldn't try to remove constness of a string returned by c_str():

char * b = s.c_str();

but you can pass an address of std::string's internal buffer directly:

int res = stem(z, static_cast<char*>(&s[0]), s.length());
LihO
  • 41,190
  • 11
  • 99
  • 167
1

If stem() is going to modify the string, then make a copy of it:

char * scpy= strdup( s.c_str()) ;
int res = stem(z, scpy, strlen( scpy)); 
free( scpy) ;
woolstar
  • 5,063
  • 20
  • 31
0

Use const_cast:

int res = stem(z, const_cast<char*>(s.c_str()), s.length()+1);
free_stemmer(z);
return s.substr(0,res);

Note the length+1 expression which might (or might not) be needed. C-style strings (char*) have an additional null terminator (zero byte, equivalent "\0") at the end. Your stem function may (or may not) expect a null terminator at the end of the string - try both variants.

Note also that "stem" function should not try to modify the string, otherwise bad things may happen (warning based on @David Heffernan's comment)

DarkWanderer
  • 8,739
  • 1
  • 25
  • 56
0
.c_str()

Just returns a pointer to the data, I would update the stem function to accept a 'const char*' unless you are wanting to modify the data in the string, in that case you should pass it as a new string object.

If you can't edit the stem function you can cast it:

int res = stem(z, const_cast<char*>(s.c_str()), s.length());
user3053099
  • 136
  • 2
-1

It's not good to do this, but nothing stops you:

#include <iostream>
#include <string>
using namespace std;

void foo(char *ch)
{
  ch[0] = 'B';
}

int main()
{
  string str = "helo world";

  char *ch = const_cast<char *>(str.c_str());

  foo(ch);

  // Belo world
  cout << str << endl;

  return 0;
}
gongzhitaao
  • 6,566
  • 3
  • 36
  • 44