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*?

7
  • 1
    @GMan: there are loads of reasons, the principal one being invoking functions in a C API? Commented Nov 17, 2010 at 18:26
  • 2
    @Gman Because I need to pass foobar variable to UDT's inet_pton function which takes only char* type variables. Commented Nov 17, 2010 at 18:28
  • @GMan, many functions still require (char*), it's mostly avoidable in C++, but not completely. Commented Nov 17, 2010 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<char>? We can better answer the question if he asked the goal and not the step. @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...) Commented Nov 17, 2010 at 18:30
  • 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). Commented Nov 17, 2010 at 18:47

4 Answers 4

47

Use foobar.c_str().

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

Sign up to request clarification or add additional context in comments.

Comments

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;
}

4 Comments

Use std::vector, never use new T[].
@GMan - thanks - I always default to very C-style behavior when a question asks about pointers, though in C++ land I know I should stick to teaching with the C++-level stuff first.
Why strncpy and not strcpy?
it's the safe version of strcpy.. gets length as argument so it doesn't go beyond array's max index.
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.

9 Comments

Should be str.length()+1 because length does not count the null byte.
Use std::vector, never use new T[].
@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: You can be as poetic as you'd like, there's literally no reason to use new T[] in place of std::vector<T>, or scoped_ptr/unique_ptr<T[]>. 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.
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.
|
3
const char* foobar2 = foobar.c_str();

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.