Thread: c_str like function implementation

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    11

    Question c_str like function implementation

    Hi...

    Does anyone know how to implement a function that returns a const char* for use in this situation:

    Code:
    class foo
    {
    protected:
       int i_size;
       char* c_data;  // not necesarily null terminated
    ...
    public:
       const char* c_str()
       {
           // - how to implement ?
           // - should add a null terminator to c_data
           // - not neccesary: possybitlity of aditional manipulation of i_data
           //   ( concat with another string )
           // - only the returned string should contain the changes - i_data should
           //    not be changed in the process
       }
    ...
    };
    
    void bar( const char* c  )
    {
        // operations on the null terminated c string
    }
    
    in main:
       foo test( "abc" );
       bar( test.c_str() );    // this part uses c_str() function to convert data to the bar function
                                        // input type ( const char* )
    The part that is causing problems is that I don't want to use malloc in c_str() since that would produce a memory leak in such a case.

    Any ideas anyone?


    Thanks, Domen.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Assuming you reserve space in c_data to hold an extra zero (note that you don't necessarily need to put the zero in there in all places where c_data content is updated), you can implement c_str() as:
    Code:
       const char* c_str()
       {
          c_data[i_size] = 0;
          return c_data;
       }
    Obviously, if you need to concatenate multiple strings, this won't work - then you need to use some other type of buffer. If re-entrancy is not a problem, you could implement a further char pointer member of your class, initialize it to 0, and when you need to produce your c_str() result, delete the old one, and allocate a large enough buffer for your string.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    On a side note, c_str() really, really should be const.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, c_str() should be const because it returns a pointer to its buffer which shouldn't be modified. But I would say it's stupid in the first place not to NULL terminate strings.
    You could also add operator const char* instead of c_str() which IMHO is my preferred way of implementation. Makes it possible to use it more like as if it was a raw char array.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You could also add operator const char* instead of c_str() which IMHO is my preferred way of implementation. Makes it possible to use it more like as if it was a raw char array.
    I suggest reading GotW #19: Automatic Conversions
    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

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, they're dangerous and all that, due to C/C++ silly implicit conversions, but they are so much more convenient plus it makes it more like a "true" string.
    MFC's CString has an operator const char* and thank goodness for that.
    So anyway, use with care and use your head and debugger.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Gosh. **shakes head* You can't say that stuff Elysia.

    Yes, they're dangerous and all that, due to C/C++ silly implicit conversions
    Exactly how you classify implicit conversions as silly. Remember we are talking about a strongly typed language. How else you'd expect the following code to compile without having to explicitly cast every operand and the operation itself?

    Code:
    double res;
    float oper1;
    int oper2;
    
    // ...
    
    res = oper1 + oper2;
    but they are so much more convenient plus it makes it more like a "true" string.
    If they need to look like a c-string they should be a c-string.

    MFC's CString has an operator const char* and thank goodness for that.
    Go you. It still doesn't mean it's a smart move. MFC hardly qualifies as a good example we all shall follow.

    So anyway, use with care and use your head and debugger.
    And exactly how is that different from using a c-string if you do need one or a string-like class without the implicit conversion? With the addition you can't use the debugger so effectively if you have to step through your code to find the bug, whereas removing the implicit conversion from your class will allow you to correct your bug at compile-time.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Mario F. View Post
    Exactly how you classify implicit conversions as silly. Remember we are talking about a strongly typed language. How else you'd expect the following code to compile without having to explicitly cast every operand and the operation itself?

    Code:
    double res;
    float oper1;
    int oper2;
    
    // ...
    
    res = oper1 + oper2;
    It means we should have a way to remove implicit conversion in code where we do not want them. Such as returning const char* operator. Implicit conversions do more harm than good here.

    If they need to look like a c-string they should be a c-string.
    Sigh, no... C-style strings bad. Bad. String classes good.

    Go you. It still doesn't mean it's a smart move. MFC hardly qualifies as a good example we all shall follow.
    Never said it was a smart move... or good practice.

    And exactly how is that different from using a c-string if you do need one? With the addition you can't use the debugger so effectively if you have to step through your code to find the bug, whereas removing the implicit conversion from your class will allow you to correct your bug at compile-time.
    Simplicity and convenience.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Elysia View Post
    Yes, they're dangerous and all that, due to C/C++ silly implicit conversions, but they are so much more convenient plus it makes it more like a "true" string.
    MFC's CString has an operator const char* and thank goodness for that.
    So anyway, use with care and use your head and debugger.
    Yeah, C++ has a lot of "silly" things like namespaces, C++ casts, references... Who need those things anyways?

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, don't take that the wrong way.
    I know you can complain about implicit conversion in a lot of classes, but references and namespaces aren't bad things. C++ casts aren't bad either, I'm just not too prone in using them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by Elysia View Post
    It means we should have a way to remove implicit conversion in code where we do not want them. Such as returning const char* operator. Implicit conversions do more harm than good here.
    But you yourself said it would be a good idea!

    Quote Originally Posted by Elysia
    You could also add operator const char* instead of c_str() which IMHO is my preferred way of implementation. Makes it possible to use it more like as if it was a raw char array.
    How could you remove an implicit conversion you just created?

    Moving on...

    Sigh, no... C-style strings bad. Bad. String classes good
    The usual misconception. The same thing with arrays and other "evils".

    No. c-style strings aren't bad. I specifically said "you should use them when you need them". I don't go about incurring in the extra overhead of std::string if I can create c-strings to feed some library demands. Just an example.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Mario F. View Post
    But you yourself said it would be a good idea!
    I don't consider overloading an operator in a class as an implicit conversion, though.
    Implicit conversion is calling a bool constructor when passing an int argument.

    The usual misconception. The same thing with arrays and other "evils".

    No. c-style strings aren't bad. I specifically said "you should use them when you need them". I don't go about incurring in the extra overhead of std::string if I can create c-strings to feed some library demands. Just an example.
    With the right implementation, you never need to use them at all. CString has GetBuffer to cover char* and const char* operator for covering const char*. No C-style strings, only CString.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I don't consider overloading an operator in a class as an implicit conversion, though.
    In this case you are defining a conversion function.

    Implicit conversion is calling a bool constructor when passing an int argument.
    The C++ Standard section 12.3 states: "At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value." Clearly it regards conversion functions as a means of implicit conversion.

    Examples of explicit conversion would be having to explicitly use a constructor, or having to use a function like c_str() to perform the conversion.

    By the way, built-in types do not have constructors.
    Last edited by laserlight; 02-13-2008 at 10:36 AM. Reason: Clarification on explicit conversion.
    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
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    OK then, conversion functions are okay, but implicit conversion can be a pain.
    The compiler should be able to call the conversion function when calling a function that takes a const char* for example, but calling it to implicitly convert a string to char* so you can subtract pointers may not be what you want.
    It would be nice if such things could be restricted.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Oh no.

    Anyway, I don't really see what would be the reason not to keep c_data null-terminated (your comments in foo are somewhat confusing - despite of the attempt at Hungarian notation, you keep mentioning something called i_data)? If foo is a string-like class what additional modifications should c_str possibly perform? If foo is not a string-like class, why should it have a method called c_str?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Brand new to C need favor
    By dontknowc in forum C Programming
    Replies: 5
    Last Post: 09-21-2007, 10:08 AM
  2. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  3. Bisection Method function value at root incorrect
    By mr_glass in forum C Programming
    Replies: 3
    Last Post: 11-10-2005, 09:10 AM
  4. C++ compilation issues
    By Rupan in forum C++ Programming
    Replies: 1
    Last Post: 08-22-2005, 05:45 AM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM