27

Possible Duplicate:
Convert std::string to const char* or char*

void Foo::bar(const std::string& foobar) {
    // ...
    const char* foobar2 = (char*)foobar;
    // ...
}

That does not work and I get an error during compilation about invalid casting.

Is there some other way to convert std::string to const char*?

Community
  • 1
  • 1
Richard Knop
  • 81,041
  • 149
  • 392
  • 552
  • 1
    @GMan: there are loads of reasons, the principal one being invoking functions in a C API? – André Caron Nov 17 '10 at 18:26
  • 2
    @Gman Because I need to pass foobar variable to UDT's inet_pton function which takes only char* type variables. – Richard Knop Nov 17 '10 at 18:28
  • @GMan, many functions still require (char*), it's mostly avoidable in C++, but not completely. – Aaron H. Nov 17 '10 at 18:28
  • 5
    @Andre @Aaron: I rarely ever do this. Do you really think a beginner knows the best way to go about something? Does he actually want `const char*`, or a `char*`? Should he use `&foobar[0]`, or a `std::vector`? We can better answer the question if he [asked the goal and not the step](http://www.catb.org/esr/faqs/smart-questions.html). @Richard: I see one that takes a `const char*` and a `void*`, nothing about a `char*` anywhere. In which case, as suspected, you just want a `const char*` and therefore `c_str` and not a `char*`. (@And @Aar: Oh look at that...) – GManNickG Nov 17 '10 at 18:30
  • `inet_pton(3)` takes `const char*`, as most sane C APIs do. Then, sure, there are insane ones ... – Nikolai Fetissov Nov 17 '10 at 18:31
  • @GMan Sorry, you are right. It takes const char*. Sorry for confusion. – Richard Knop Nov 17 '10 at 18:44
  • 3
    @GMan: "I'm hoping not to get fired from my job for failing to write the code I'm supposed to. Any ideas?". Ask the goal, not the step ;-p (You're right, of course). – Steve Jessop Nov 17 '10 at 18:47

4 Answers4

47

Use foobar.c_str().

You might find this link useful: http://www.cppreference.com/wiki/string/start

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
11

std::string::c_str() gets you a const char* pointer to a character array that represents the string (null-terminated).

You should not manipulate the data this pointer points to, so if you need to do that, copy the data.

Double edit - doing it in a more C++ fashion

Since it is nicer to avoid the use of raw pointers and arrays where possible, you can also get the data into an std::vector<char>

#include <string>
#include <vector>

int main()
{
    std::string str = "Hello";
    std::vector<char> cvec(str.begin(), str.end()); 

    // do stuff
}

edit this is more like C since it uses raw pointers and explicitly allocates mem

#include <string>
#include <cstring>

int main()
{
    std::string str = "Hello";
    char *cptr = new char[str.size()+1]; // +1 to account for \0 byte
    std::strncpy(cptr, str.c_str(), str.size());

    // do stuff...
    delete [] cptr;
}
wkl
  • 77,184
  • 16
  • 165
  • 176
4

You're going to get a lot of kinda incorrect answers about str.c_str() here. :) While c_str() is indeed useful, please keep in mind that this will not actually convert the string into a char*, but rather return the contents of the string as a const char*. And this is a big difference!

What's important here is that the pointer you obtain from c_str() is valid only as long as the given string object exists. So this would be terribly wrong:

class Something {
    const char* name;
public:
    Something(const std::string& pname) {
        this->name = pname.c_str(); /* wrong! the pointer will go wrong as the object from the parameter ceases to exist */
    }
};

So if you want to convert, as in: create a new value which will be independent of the original std::string, then you'll want to do something like this:

char* convert(const std::string& str) {
    char* result = new char[str.length()+1];
    strcpy(result,str.c_str());
    return result;
}

But still c_str() will be quite enough for you in most cases. Just try to think in terms of objects' time of life.

Kos
  • 70,399
  • 25
  • 169
  • 233
  • 2
    Should be `str.length()+1` because length does not count the null byte. – wkl Nov 17 '10 at 18:33
  • 2
    Use `std::vector`, never use `new T[]`. – GManNickG Nov 17 '10 at 18:33
  • @Gman - I'd rather say "think, never listen to proverbs blindly". :) Both have their applications. C++ can be used for low-level code and there's absolutely nothing wrong with low-level constructs. – Kos Nov 17 '10 at 18:36
  • 4
    @Kos: You can be as poetic as you'd like, there's literally no reason to use `new T[]` in place of `std::vector`, or `scoped_ptr`/`unique_ptr`. Unless, of course, you're trying to write code that isn't exception-safe, poorly manages its resources, etc...Just because C++ can be low level doesn't mean you can, have to, or will get away with writing poor code. – GManNickG Nov 17 '10 at 18:39
  • I'd say std::vector already is pretty low-level. There are very few reasons not to prefer it over a raw array; level of abstraction is not one of them. – Ben Nov 17 '10 at 18:44
  • @Gman: I understand your point, but let us not forget that manual memory handling, being a must in C++, is something which needs *attention*, and need for attention is not solved by using "smart" pointers - or any other language construct. Correct code is the code which is well-thought and maintainable, with clear rules of object scope and ownership. Templates being an useful tool, using them won't make the code safe automatically. Thinking is what makes the code safe. I'll stay with the C++ FQA point of view. – Kos Nov 17 '10 at 19:13
  • @Kos: Ah, you won't get along with many people in the C++ community sticking by the FQA. I find it quite contradictory to say "Correct code is the code which is well-thought and maintainable, with clear rules of object scope and ownership.", then turn around and pass a raw pointer with ***no ownership*** back from a function. Whether you like it or not, C++ is about black boxes. Something does what it's suppose to, so you use it. Teach about memory management once, then use containers everywhere else. – GManNickG Nov 17 '10 at 19:16
  • @GManNickG Hello from 2017! I totally with agree with you now. Raw pointers, brr. I hope the first few sentences of my answers are salvageable. – Kos Sep 29 '17 at 17:11
  • @Kos: Haha, nice. :) – GManNickG Sep 30 '17 at 18:49
3
const char* foobar2 = foobar.c_str();

Notice the const. Otherwise you have to copy it to a char buffer.

fabrizioM
  • 46,639
  • 15
  • 102
  • 119