Thread: Converting C++ string to C style string

  1. #1
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181

    Converting C++ string to C style string

    Code:
    string lineread = "Hello"
    char* cstr = lineread.c_str();
    Gives an error invalid conversion from 'const char*' to 'char*' [-fpermissive]

    I understand this has something to do with immutable vs mutable and that the solution, as the internet gurus say, is to make a copy. This is too Greek to me. Can someone actually add one or two lines of code to the above to make the conversion work?

  2. #2
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Wait, why isn't cstr const? You're assigning a pointer to a location in memory, why do you need this to be non-const?

    Edit : Also, why not just use strcpy?

  3. #3
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Okay I added a const but the following code gives the same error on line 4:

    Code:
    // A simple tokenizer
    string lineread = "Hello how are you"    
    const char* cstr = lineread.c_str();
    char* wordptr = strtok(cstr," ");
    invalid conversion from 'const char*' to 'char*' [-fpermissive]

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    you'll need to to use strcpy, because strtok requires a char*, not a const char*. is there a reason why you can't tokenize a string using just the tools provided by C++ for std::string?
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Quote Originally Posted by Elkvis View Post
    you'll need to to use strcpy, because strtok requires a char*, not a const char*. is there a reason why you can't tokenize a string using just the tools provided by C++ for std::string?
    Okay I made a copy and it worked:

    Code:
    // A simple tokenizer
    string lineread = "Hello how are you"    
    const char* cstr = lineread.c_str();
    char* cstringcpy = NULL;
    strcpy(cstringcpy,cstr);
    char* wordptr = strtok(cstringcpy," ");
    That is an absolutely crazy method to simply tokenize a C++ string and I do not wish to undergo five lines of code to do this ridiculously simple task.

    Please could you direct me to a simpler direct C++ way? I stress the word simple, because I've seen other solutions online that really go off on a tangent.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    In this particular case, you can just use &lineread[0] instead of lineread.c_str() and everything will work. Just don't try to add characters to the array though the char *.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    another option would be to use std::stringstream and std::getline like so:

    Code:
    std::stringstream ss("Hello how are you");
    std::string token;
    while (std::getline(ss, token, ' '))
    {
      // do something with token
    }
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    That is an absolutely crazy method to simply tokenize a C++ string and I do not wish to undergo five lines of code to do this ridiculously simple task.
    O_o

    That is an absolutely crazy thing to ask; throw those five lines in a function and call it.

    Also:

    Code:
    string lineread = "Hello how are you"
    const char* cstr = lineread.c_str();
    char* cstringcpy = NULL;
    strcpy(cstringcpy,cstr);
    char* wordptr = strtok(cstringcpy," ");
    This is a major bug.

    Also, you could be using `std::string::find_first_of' in a loop.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  9. #9
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    And I know it's nitpicky but the thing is to now set pointers equal to nullptr in lieu of NULL.

  10. #10
    Registered User
    Join Date
    Jan 2014
    Posts
    15
    Quote Originally Posted by Vespasian View Post
    Please could you direct me to a simpler direct C++ way? I stress the word simple, because I've seen other solutions online that really go off on a tangent.
    You can try Boost Tokenizer (Boost Tokenizer Overview - 1.36.0).

    Alternatively, try std::string::find and std::string::substr.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,271
    Quote Originally Posted by Vespasian
    Okay I made a copy and it worked:
    I note that you did not allocate any space for the copy.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Quote Originally Posted by laserlight View Post
    I note that you did not allocate any space for the copy.
    Excellent find!

    I was just about to post a new thread asking why the tokenizer function returns a SIGSEGV error. So then I did:

    Code:
    char* tokenizer (string inputstream)
    {
        char* cstringcpy;
        const char* cstr = inputstream.c_str();
        strcpy(cstringcpy,cstr);
        char* wordptr = (char*)malloc (50 * sizeof(char));
        wordptr = strtok(cstringcpy,"\t");
        return wordptr;
    }
    Even though I malloced wordptr, I STILL got a SIGSEGV error even though I passed wordptr on the heap.

    Then I realised the thing that wordptr pointed to is in itself was not on the heap. So then I finally did a change on line 3 to allocate the COPY in memory:

    Code:
    char* tokenizer (string inputstream)
    {
        char* cstringcpy = (char*)malloc (50 * sizeof(char));
        const char* cstr = inputstream.c_str();
        strcpy(cstringcpy,cstr);
        char* wordptr = (char*)malloc (50 * sizeof(char));
        wordptr = strtok(cstringcpy,"\t");
        return wordptr;
    }
    And I finally get no error :-) Is this why you pointed to the dangers of not assigning memory to the copy?

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,271
    You know, drawing on Elkvis' example in post #7, you could do something like this:
    Code:
    void tokenize(string input, vector<string>& tokens)
    {
        stringstream ss(input);
        string token;
        while (getline(ss, token, '\t'))
        {
            tokens.push_back(token);
        }
    }
    Look ma, no need for manual memory management!
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Jan 2014
    Posts
    15
    What laserlight is advising is called RAII, and it's one of the fundamental things to learn in C++.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    What laserlight is advising is called RAII, and it's one of the fundamental things to learn in C++.
    O_o

    The use of "RAII" is certainly part of the suggestion, but what laserlight is really advising is "Use the higher level constructs provided by the C++ standard library.".

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C-Style String and its Length
    By Sammy2011 in forum C++ Programming
    Replies: 8
    Last Post: 11-02-2011, 12:18 AM
  2. converting string to int back to string
    By thenson in forum C Programming
    Replies: 4
    Last Post: 02-03-2008, 11:21 AM
  3. Replies: 1
    Last Post: 10-27-2005, 10:24 AM
  4. C++: Converting Numeric String to Alpha String
    By JosephCardsFan in forum C++ Programming
    Replies: 3
    Last Post: 02-16-2005, 07:07 AM
  5. c-style string vs. c++-style strings
    By Mbrio in forum C++ Programming
    Replies: 3
    Last Post: 02-10-2002, 12:26 PM

Tags for this Thread