C Style Strings

Discussion in 'C++' started by scroopy, Jun 1, 2006.

  1. scroopy

    scroopy Guest

    Hi,

    I've always used std::string but I'm having to use a 3rd party library
    that returns const char*s. Given:

    char* pString1 = "Blah ";
    const char* pString2 = "Blah Blah";

    How do I append the contents of pString2 to pString? (giving "Blah
    Blah Blah")

    I looked at strcat but that crashes with an unhandled exception.

    Thanks
    scroopy, Jun 1, 2006
    #1
    1. Advertising

  2. scroopy

    Guest

    scroopy wrote:
    > Hi,
    >
    > I've always used std::string but I'm having to use a 3rd party library
    > that returns const char*s. Given:
    >
    > char* pString1 = "Blah ";
    > const char* pString2 = "Blah Blah";
    >
    > How do I append the contents of pString2 to pString? (giving "Blah
    > Blah Blah")
    >
    > I looked at strcat but that crashes with an unhandled exception.


    That's easy, do it the C way:

    char* result=new char[strlen(s1)+strlen(s2)+1];
    strcpy(result,s1);
    strcat(result,s2);

    Regards
    Jiri Palecek
    , Jun 1, 2006
    #2
    1. Advertising

  3. scroopy

    Kai-Uwe Bux Guest

    scroopy wrote:

    > Hi,
    >
    > I've always used std::string but I'm having to use a 3rd party library
    > that returns const char*s. Given:
    >
    > char* pString1 = "Blah ";
    > const char* pString2 = "Blah Blah";
    >
    > How do I append the contents of pString2 to pString? (giving "Blah
    > Blah Blah")


    a) Keep using std::string for your own stuff. The std::string class has
    methods that allow you to interact with C-style string interfaces of
    libraries.

    b) Note that in your example above, pString1 is initialized to a const
    string. Any attempt to modify that string would be undefined behavior. The
    danger lies in not declaring pString1 as a char const *.

    c) You could do:

    #include <string>
    #include <algorithm>

    char * strdup ( std::string str ) {
    char * result = new char [ str.length() +1 ];
    std::copy( str.begin(), str.end(), result );
    result[ str.length() ] = 0;
    return ( result );
    }

    int main ( void ) {
    char * pString1 = "Blah ";
    char const * pString2 = "Blah Blah";
    pString1 = strdup( std::string( pString1 ).append( pString2 ) );
    }


    However, I would prefer to use std::string for my own stuff:

    #include <string>

    int main ( void ) {
    std::string pString1 = "Blah "; // rhs returned by some library
    std::string pString2 = "Blah Blah"; // rhs returned by some library
    pString1.append( pString2 );
    }


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 1, 2006
    #3
  4. On Thu, 01 Jun 2006 08:35:36 +0100, scroopy <>
    wrote:
    >I've always used std::string but I'm having to use a 3rd party library
    >that returns const char*s.


    First you need to find out if you 'own' the returned string, i.e. if
    you must free (maybe delete) the returned char*. Good C libraries
    usually don't require the user to call free.

    >Given:
    >
    >char* pString1 = "Blah ";
    >const char* pString2 = "Blah Blah";
    >
    >How do I append the contents of pString2 to pString? (giving "Blah
    >Blah Blah")


    You can append a const char* to a std::string:

    string myString = "Blah ";
    const char* s = myLibFunc (...);
    if (s) {
    myString += s; // or myString.append(s);
    }
    // free (s); // if it's a bad lib

    Best wishes,
    Roland Pibinger
    Roland Pibinger, Jun 1, 2006
    #4
  5. scroopy

    kwikius Guest

    scroopy wrote:
    > Hi,
    >
    > I've always used std::string but I'm having to use a 3rd party library
    > that returns const char*s. Given:
    >
    > char* pString1 = "Blah ";
    > const char* pString2 = "Blah Blah";
    >
    > How do I append the contents of pString2 to pString? (giving "Blah
    > Blah Blah")


    #include <malloc.h>
    #include <cstring>

    char* concat(const char * str1, const char* str2)
    {
    char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);
    if( result != NULL){
    strcpy(result,str1);
    strcat(result, str2);
    }
    return result;
    }

    #include <iostream>
    #include <string>

    char* pString1 = "Blah ";
    const char* pString2 = "Blah Blah";


    int main()
    {
    // C-style
    char* str = concat(pString1,pString2);
    if(str != NULL){
    std::cout << str <<'\n';
    free(str);
    }

    // C++ style
    std::string str1=std::string(pString1) + pString2;
    std::cout << str1 <<'\n';
    }

    I'm not sure if that is the optimal C method. Its interesting to note
    how much better the C++ version is though!

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #5
  6. scroopy

    Richard Bos Guest

    "kwikius" <> wrote:

    > scroopy wrote:
    > > How do I append the contents of pString2 to pString? (giving "Blah
    > > Blah Blah")

    >
    > #include <malloc.h>
    > #include <cstring>


    This is not C...

    > char* concat(const char * str1, const char* str2)
    > {
    > char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);


    ....and this is the wrong way to do this in C. And, really, also in C++:
    use new.

    So don't cross-post stuff like that. Follow-ups set.

    Richard
    Richard Bos, Jun 1, 2006
    #6
  7. scroopy

    kwikius Guest

    Roland Pibinger wrote:

    > First you need to find out if you 'own' the returned string, i.e. if
    > you must free (maybe delete) the returned char*. Good C libraries
    > usually don't require the user to call free.


    Out of interest ... What is a good C library resource management
    strategy? ... for example (say) modifying the following example

    char* concat(const char * str1, const char* str2)
    {
    char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);
    if( result != NULL){
    strcpy(result,str1);
    strcat(result, str2);
    }
    return result;
    }

    char* pString1 = "Blah ";
    const char* pString2 = "Blah Blah";

    int main()
    {
    char* str = concat(pString1,pString2);
    if(str != NULL){
    std::cout << str <<'\n';
    free(str); // How to avoid this in C-style?
    }
    }

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #7
  8. Richard Bos said:

    > "kwikius" <> wrote:
    >
    >> scroopy wrote:
    >> > How do I append the contents of pString2 to pString? (giving "Blah
    >> > Blah Blah")

    >>
    >> #include <malloc.h>
    >> #include <cstring>

    >
    > This is not C...


    ....and it's not C++ either, so I'm not sure why you set followups to clc++.

    The entire article, in fact (his, not yours), was a classic example of the
    kind of thing you get in the Hackitt and Scarper school of programming.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
    Richard Heathfield, Jun 1, 2006
    #8
  9. scroopy

    kwikius Guest

    Richard Bos wrote:
    > "kwikius" <> wrote:
    >
    > > scroopy wrote:
    > > > How do I append the contents of pString2 to pString? (giving "Blah
    > > > Blah Blah")

    > >
    > > #include <malloc.h>
    > > #include <cstring>

    >
    > This is not C...
    >
    > > char* concat(const char * str1, const char* str2)
    > > {
    > > char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);

    >
    > ...and this is the wrong way to do this in C.


    Out of interest what is the right way? BTW... It would seem to me to
    make sense to cross-post this to comp.lang.c as it is somewhat O.T. for
    C++. I think It makes sense in terms of a language comparison though,
    don't you think?

    > And, really, also in C++:


    hmmm... Touchy arent we? I showed a C++ way in my previous post.

    > use new.


    Sure? .. The best way is not to allocate resources the users has to
    manage , isnt it?.

    > So don't cross-post stuff like that. Follow-ups set.


    Hmm... Are you sure I wouldnt get a better answer to the how to do it
    in C question in a C newsgroup?

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #9
  10. scroopy

    kwikius Guest

    Richard Heathfield wrote:
    > Richard Bos said:
    >
    > > "kwikius" wrote:
    > >
    > >> scroopy wrote:
    > >> > How do I append the contents of pString2 to pString? (giving "Blah
    > >> > Blah Blah")
    > >>
    > >> #include <malloc.h>
    > >> #include <cstring>

    > >
    > > This is not C...

    >
    > ...and it's not C++ either, so I'm not sure why you set followups to clc++.
    >
    > The entire article, in fact (his, not yours), was a classic example of the
    > kind of thing you get in the Hackitt and Scarper school of programming.


    Thats great! Thanks! Its always good to get positive feedback!

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #10
  11. On 1 Jun 2006 01:29:33 -0700, "kwikius"
    <> wrote:
    >Roland Pibinger wrote:
    >
    >> First you need to find out if you 'own' the returned string, i.e. if
    >> you must free (maybe delete) the returned char*. Good C libraries
    >> usually don't require the user to call free.

    >
    >Out of interest ... What is a good C library resource management
    >strategy? ... for example (say) modifying the following example
    >
    >char* concat(const char * str1, const char* str2)


    This is almost the declaration of strcat, but strcat operates on the
    given buffer and doesn't allocate anything. AFAIK, no Standard C
    library functions returns anything to be freed.
    Your example could be rewritten as:

    char* concat (const char * str1, const char* str2, char* result,
    size_t resultLen);

    The function returns NULL when the 'contract' (string concatenation)
    cannot be fulfilled, e.g. because the result-buffer is to small.
    resultLen is for additional safety.

    Best wishes,
    Roland Pibinger
    Roland Pibinger, Jun 1, 2006
    #11
  12. scroopy

    kwikius Guest

    Roland Pibinger wrote:
    > On 1 Jun 2006 01:29:33 -0700, "kwikius"
    > <> wrote:


    [...]

    > >Out of interest ... What is a good C library resource management
    > >strategy? ... for example (say) modifying the following example
    > >
    > >char* concat(const char * str1, const char* str2)

    >
    > This is almost the declaration of strcat, but strcat operates on the
    > given buffer and doesn't allocate anything. AFAIK, no Standard C
    > library functions returns anything to be freed.
    > Your example could be rewritten as:
    >
    > char* concat (const char * str1, const char* str2, char* result,
    > size_t resultLen);
    >
    > The function returns NULL when the 'contract' (string concatenation)
    > cannot be fulfilled, e.g. because the result-buffer is to small.
    > resultLen is for additional safety.


    Thanks for the answer. So the answer to the question of a library
    resource management strategy in C is that there isnt one. Everything to
    do with resource managment should be done manually by the user, whereas
    in C++ it is usual to automate resource management thus dramatically
    simplifying life for the user. That would seem to be a clear win for
    C++ over C!

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #12
  13. scroopy

    Ian Collins Guest

    kwikius wrote:
    > Richard Bos wrote:
    >
    >>"kwikius" <> wrote:
    >>
    >>
    >>>scroopy wrote:
    >>>
    >>>>How do I append the contents of pString2 to pString? (giving "Blah
    >>>>Blah Blah")
    >>>
    >>>#include <malloc.h>
    >>>#include <cstring>

    >>
    >>This is not C...
    >>
    >>
    >>>char* concat(const char * str1, const char* str2)
    >>>{
    >>> char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);

    >>
    >>...and this is the wrong way to do this in C.

    >
    >
    > Out of interest what is the right way? BTW...


    He was probably referring to the cast, which isn't used in C due to
    implicit conversion from void*

    --
    Ian Collins.
    Ian Collins, Jun 1, 2006
    #13
  14. On 1 Jun 2006 02:20:01 -0700, "kwikius"
    <> wrote:
    >So the answer to the question of a library
    >resource management strategy in C is that there isnt one.


    Let the user provide the necessary resources. Actually, IMO, that's a
    very good resource management strategy. In C and C++.

    >Everything to
    >do with resource managment should be done manually by the user, whereas
    >in C++ it is usual to automate resource management thus dramatically
    >simplifying life for the user. That would seem to be a clear win for
    >C++ over C!


    Yes, the C++ advantage stems from RAII.

    Best wishes,
    Roland Pibinger
    Roland Pibinger, Jun 1, 2006
    #14
  15. On 1 Jun 2006 01:57:05 -0700, "kwikius"
    <> wrote:
    >Richard Heathfield wrote:
    >> The entire article, in fact (his, not yours), was a classic example of the
    >> kind of thing you get in the Hackitt and Scarper school of programming.

    >
    >Thats great! Thanks! Its always good to get positive feedback!


    BTW, an interesting C-string library can be found here:
    http://synesis.com.au/software/cstring/index.html

    Best wishes,
    Roland Pibinger
    Roland Pibinger, Jun 1, 2006
    #15
  16. scroopy

    peter koch Guest

    Ian Collins skrev:

    > kwikius wrote:
    > > Richard Bos wrote:
    > >
    > >>"kwikius" <> wrote:
    > >>
    > >>
    > >>>scroopy wrote:
    > >>>
    > >>>>How do I append the contents of pString2 to pString? (giving "Blah
    > >>>>Blah Blah")
    > >>>
    > >>>#include <malloc.h>
    > >>>#include <cstring>
    > >>
    > >>This is not C...
    > >>
    > >>
    > >>>char* concat(const char * str1, const char* str2)
    > >>>{
    > >>> char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);
    > >>
    > >>...and this is the wrong way to do this in C.

    > >
    > >
    > > Out of interest what is the right way? BTW...

    >
    > He was probably referring to the cast, which isn't used in C due to
    > implicit conversion from void*


    To explicitise an implicit conversion does not stop it being C. It just
    starts it being C++ as well.

    /Peter

    >
    > --
    > Ian Collins.
    peter koch, Jun 1, 2006
    #16
  17. scroopy

    kwikius Guest

    Roland Pibinger wrote:
    > On 1 Jun 2006 01:57:05 -0700, "kwikius"
    > <> wrote:
    > >Richard Heathfield wrote:
    > >> The entire article, in fact (his, not yours), was a classic example of the
    > >> kind of thing you get in the Hackitt and Scarper school of programming.

    > >
    > >Thats great! Thanks! Its always good to get positive feedback!

    >
    > BTW, an interesting C-string library can be found here:
    > http://synesis.com.au/software/cstring/index.html


    It looks like a C++ style string written in C! The telling part is the
    create and destroy functions, which would of course be replaced by
    language facilities if written in C++.

    regards
    Andy Little
    kwikius, Jun 1, 2006
    #17
  18. scroopy

    Ian Collins Guest

    peter koch wrote:
    > Ian Collins skrev:
    >>
    >>He was probably referring to the cast, which isn't used in C due to
    >>implicit conversion from void*

    >
    >
    > To explicitise an implicit conversion does not stop it being C. It just
    > starts it being C++ as well.
    >

    No it doesn't, but try telling that to the folks down the hall, they get
    very hot under the collar.

    There is a valid reason for not doing explicit casts on function returns
    in C, it masks missing headers (not an issue in C++).

    --
    Ian Collins.
    Ian Collins, Jun 1, 2006
    #18
  19. kwikius wrote:
    > scroopy wrote:


    > > I've always used std::string but I'm having to use a 3rd party library
    > > that returns const char*s. Given:


    I assume most of the code is C++ and that you have to handle C strings
    as well.
    I'm facing the same problem (plus a third party string class...). My
    approach
    was to get rid of the C strings as soon as possible. And only convert
    back at
    the last minute.

    > > char* pString1 = "Blah ";
    > > const char* pString2 = "Blah Blah";
    > >
    > > How do I append the contents of pString2 to pString? (giving "Blah
    > > Blah Blah")


    std::string result = std::string(pString1) + pString2;


    > #include <malloc.h>

    not a valid header (in either language)
    #include <cstdlib>

    or better yet don't use malloc(). Mixing malloc() and new can be hairy.

    > #include <cstring>


    when using C headers decide which sort to use. If you use this you need
    to
    namespace qualify your C calls.

    > char* concat(const char * str1, const char* str2)
    > {
    > char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);


    std::malloc() or use new or use std::string

    > if( result != NULL){
    > strcpy(result,str1);

    std::strcpy() etc.

    > strcat(result, str2);
    > }
    > return result;
    > }


    <snip>

    --
    Nick Keighley
    Nick Keighley, Jun 1, 2006
    #19
  20. scroopy

    SuperKoko Guest

    kwikius wrote:
    > Roland Pibinger wrote:
    > > On 1 Jun 2006 01:29:33 -0700, "kwikius"
    > > <> wrote:

    >
    > [...]
    >
    > > >Out of interest ... What is a good C library resource management
    > > >strategy? ... for example (say) modifying the following example
    > > >
    > > >char* concat(const char * str1, const char* str2)

    > >
    > > This is almost the declaration of strcat, but strcat operates on the
    > > given buffer and doesn't allocate anything. AFAIK, no Standard C
    > > library functions returns anything to be freed.
    > > Your example could be rewritten as:
    > >
    > > char* concat (const char * str1, const char* str2, char* result,
    > > size_t resultLen);
    > >
    > > The function returns NULL when the 'contract' (string concatenation)
    > > cannot be fulfilled, e.g. because the result-buffer is to small.
    > > resultLen is for additional safety.

    >
    > Thanks for the answer. So the answer to the question of a library
    > resource management strategy in C is that there isnt one. Everything to
    > do with resource managment should be done manually by the user, whereas
    > in C++ it is usual to automate resource management thus dramatically
    > simplifying life for the user. That would seem to be a clear win for
    > C++ over C!
    >

    Even if it is popular in C. Many C libraries use another way:
    GString is a good example of a clean C interface:
    http://developer.gnome.org/doc/API/glib/glib-strings.html#G-STRING-FREE

    Instead of having to call "free", the user must call a library-provided
    resource deallocating function.

    Using internally, functions which use with the any range of
    user-provided memory (or iterators) is a good way to reuse efficiently
    code.
    However, in C, as in C++, it is good to encapsulate things and to
    provide comfortable interfaces.
    SuperKoko, Jun 1, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kurt Krueckeberg
    Replies:
    2
    Views:
    697
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=
    Nov 17, 2004
  2. Rick

    Comparing strings from within strings

    Rick, Oct 21, 2003, in forum: C Programming
    Replies:
    3
    Views:
    369
    Irrwahn Grausewitz
    Oct 21, 2003
  3. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    740
    Malcolm
    Jun 24, 2006
  4. Kza
    Replies:
    4
    Views:
    413
    Andrew Koenig
    Mar 3, 2006
  5. Ken Varn
    Replies:
    0
    Views:
    430
    Ken Varn
    Apr 26, 2004
Loading...

Share This Page