String Concatenation Using Pointers No strcat()

Discussion in 'C Programming' started by raidvvan@yahoo.com, Dec 7, 2007.

  1. Guest

    Hi there,

    I am having a bit of an issue when trying to concatenate strings using
    char * pointers.

    Here is what I need:

    I need to add a list of ID's to a string that is a SQL statement so
    that I can end up with:
    SELECT DISTINCT Object_ID FROM Object_Interactions WHERE Object_ID IN
    ('UUID1', 'UUID2') ORDER BY Object_ID ASC;

    Here is what I am doing:

    struct object_type
    {
    char *id; /* UUID = 32 chars length */
    };

    void strappnd(char *dest, char *src)
    {
    /* appends one string to another */
    while (*src != '\0')
    *dest++ = *src++;

    *dest = '\0';
    }

    char *buffer = NULL;
    char *sql = NULL;
    int j = 0;
    int buffer_size = 0;
    int object_count = 0;

    object_count = 2; /* this is actually a calculated value... */

    /* I have used malloc() and then assigned a value to object_list[j]-
    >id and that was OK */


    buffer_size = 32 * object_count + strlen("''") * object_count +
    strlen(", ") * (object_count - 1) + 1;

    buffer = (char *)malloc(buffer_size * sizeof(char)); /* I know about
    pointer casting issue and malloc without stdlib.h but there is too
    much code to be changed... */
    strcpy(buffer, "");

    for (j=0; j<object_count; j++)
    {
    printf("buffer=%s\n", buffer);

    strcat(buffer, "'");
    strappnd(buffer, object_list[j]->id);

    /* we must not end the sequence with a comma */
    if (j < object_count - 1)
    strcat(buffer, "', '");
    else
    strcat(buffer, "'");
    }
    sql = (char *)malloc((100 + buffer_size + 1) * sizeof(char));
    sprintf(sql, "SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
    Object_ID IN (%s) ORDER BY Object_ID ASC;", buffer);
    free(buffer);

    printf("sql=%s\n", sql);

    Result:
    sql = SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
    Object_ID IN (UUID1') ORDER BY Object_ID ASC;

    I have been trying and searching for a couple of days for all kinds of
    solutions but I can't seem to find anything and I can't make it work.
    Basically the question is how to transform a const char * into a char
    *. Does simple casting work? Is it safe? What else can I do because
    I keep hitting this wall, and I can't use the standard <string.h>
    functions because most of them expect a char const * as opposed to
    char * in one of the arguments.

    I have been looking on the Internet and forums, but for most cases
    strcat is being used and seems to be enough.
    I found interesting variations of strcat, but they don't seem to work
    and I don't have any more time for this. After finding libAPR I even
    thought of using it, but I only need one function from this library
    and plus the application must be portable on Linux, Mac, Windows...

    Any help on how to do string concatenation with char * or how to
    convert const char * to char * would be greatly appreciated.

    Other than that, C is just great. :)

    Thanks very much.
    Ovidiu Anghelidi
     
    , Dec 7, 2007
    #1
    1. Advertising

  2. Mark Bluemel Guest

    wrote:
    > Hi there,
    >
    > I am having a bit of an issue when trying to concatenate strings using
    > char * pointers.


    [Snip]

    > void strappnd(char *dest, char *src)
    > {
    > /* appends one string to another */
    > while (*src != '\0')
    > *dest++ = *src++;
    >
    > *dest = '\0';
    > }


    This is strcpy() surely?

    > I have been trying and searching for a couple of days for all kinds of
    > solutions but I can't seem to find anything and I can't make it work.


    Your presentation of the problem is too verbose and ill-formed for me to
    make sense of it.

    Surely before posting you could have boiled down your problem to a
    really simple testcase?

    If you simply want to process something like this :-

    char *uuids[4] = { "UUID1", "UUID2", "UUID3", "UUID4" };

    into

    char *all_uuids; /*containing "UUID1, UUID2, UUID3, UUID4" */

    What about this :-

    #include <stdio.h>
    #include <string.h>
    int main(void) {
    char *uuids[4] = {"UUID1", "UUID2", "UUID3", "UUID4"};
    char *all_uuids = malloc(1024); /* arbitrary size
    * and needs error check
    */
    int i;
    for (i = 0; i < 4; i++) {
    if (i>0) {
    strcat(all_uuids,", ");
    }
    strcat(all_uuids,uuids);
    }
    printf("all the uuids are (%s)\n",all_uuids);
    }
     
    Mark Bluemel, Dec 7, 2007
    #2
    1. Advertising

  3. writes:

    > I am having a bit of an issue when trying to concatenate strings using
    > char * pointers.
    >
    > Here is what I need:
    >
    > I need to add a list of ID's to a string that is a SQL statement so
    > that I can end up with:
    > SELECT DISTINCT Object_ID FROM Object_Interactions WHERE Object_ID IN
    > ('UUID1', 'UUID2') ORDER BY Object_ID ASC;
    >
    > Here is what I am doing:
    >
    > struct object_type
    > {
    > char *id; /* UUID = 32 chars length */
    > };
    >
    > void strappnd(char *dest, char *src)
    > {
    > /* appends one string to another */
    > while (*src != '\0')
    > *dest++ = *src++;
    >
    > *dest = '\0';
    > }


    Basic problem is that you believe the comment not the code. The
    above doe snot append. It overwrites.

    > char *buffer = NULL;
    > char *sql = NULL;
    > int j = 0;
    > int buffer_size = 0;
    > int object_count = 0;
    >
    > object_count = 2; /* this is actually a calculated value... */
    >
    > /* I have used malloc() and then assigned a value to object_list[j]-
    >>id and that was OK */

    >
    > buffer_size = 32 * object_count + strlen("''") * object_count +
    > strlen(", ") * (object_count - 1) + 1;
    >
    > buffer = (char *)malloc(buffer_size * sizeof(char)); /* I know about
    > pointer casting issue and malloc without stdlib.h but there is too
    > much code to be changed... */
    > strcpy(buffer, "");
    >
    > for (j=0; j<object_count; j++)
    > {
    > printf("buffer=%s\n", buffer);
    >
    > strcat(buffer, "'");
    > strappnd(buffer, object_list[j]->id);


    If you had just gone on to use strcat it would have worked.

    > /* we must not end the sequence with a comma */
    > if (j < object_count - 1)
    > strcat(buffer, "', '");
    > else
    > strcat(buffer, "'");
    > }
    > sql = (char *)malloc((100 + buffer_size + 1) * sizeof(char));
    > sprintf(sql, "SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
    > Object_ID IN (%s) ORDER BY Object_ID ASC;", buffer);
    > free(buffer);
    >
    > printf("sql=%s\n", sql);
    >
    > Result:
    > sql = SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
    > Object_ID IN (UUID1') ORDER BY Object_ID ASC;
    >
    > I have been trying and searching for a couple of days for all kinds of
    > solutions but I can't seem to find anything and I can't make it work.
    > Basically the question is how to transform a const char * into a char
    > *. Does simple casting work?


    Yes, but...

    > Is it safe?


    No.

    > What else can I do because
    > I keep hitting this wall, and I can't use the standard <string.h>
    > functions because most of them expect a char const * as opposed to
    > char * in one of the arguments.


    strcat has a const string argument only as the source. Personally, I
    would check the UUID lengths before adding them, and advance a buffer
    pointer as I went. You'd get some added assurance that you won't
    overflow your buffer and you can use strcpy rather than strcat.

    > Any help on how to do string concatenation with char * or how to
    > convert const char * to char * would be greatly appreciated.


    If you need to, something has probably gone very wrong.

    --
    Ben.
     
    Ben Bacarisse, Dec 7, 2007
    #3
  4. Guest

    On Dec 7, 10:54 am, Mark Bluemel <> wrote:
    > This is strcpy() surely?


    Yes, I can see that now.

    > Your presentation of the problem is too verbose


    Sorry about that. And to think that initially I wanted to post another
    2 or 3 pages of code. :)

    Thanks for the reply.
     
    , Dec 7, 2007
    #4
  5. Guest

    On Dec 7, 11:10 am, Ben Bacarisse <> wrote:

    > If you had just gone on to use strcat it would have worked.


    I tried that before, but I got segmentation fault and that's why I
    thought of replacing it. I will try again with the checking.

    > If you need to, something has probably gone very wrong.


    This is great. I kept thinking that this is the way to go.

    Thanks a lot,
    Ovidiu
     
    , Dec 7, 2007
    #5
  6. Mark Bluemel <> writes:
    [...]
    > What about this :-
    >
    > #include <stdio.h>
    > #include <string.h>
    > int main(void) {
    > char *uuids[4] = {"UUID1", "UUID2", "UUID3", "UUID4"};
    > char *all_uuids = malloc(1024); /* arbitrary size
    > * and needs error check
    > */
    > int i;
    > for (i = 0; i < 4; i++) {
    > if (i>0) {
    > strcat(all_uuids,", ");
    > }
    > strcat(all_uuids,uuids);
    > }
    > printf("all the uuids are (%s)\n",all_uuids);
    > }


    One problem with that is that strcat() has to scan the target string
    each time before appending the new string. For a small number of
    short strings like you have here, it's probably not a big deal, but
    it's an O(N**2) algorithm for something that can easily be done in
    O(N).

    An improvement would be to use strcpy() rather than strcat(), and
    update a pointer to point to the end of the string after each step.
    This still does some unnecessary scanning, but at least it doesn't
    re-scan the same string repeatedly.

    If you have a fixed number of strings to append, you might consider
    sprintf() (though the overhead of processing the format string
    might be excessive):
    sprintf(all_uuids, "%s, %s, %s, %s",
    uuids[0], uuids[1], uuids[2], uuids[3]);

    Or you can write your own routine that keeps track of the end of the
    string as it goes along.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 7, 2007
    #6
  7. Default User Guest

    wrote:

    > On Dec 7, 11:10 am, Ben Bacarisse <> wrote:
    >
    > > If you had just gone on to use strcat it would have worked.

    >
    > I tried that before, but I got segmentation fault and that's why I
    > thought of replacing it. I will try again with the checking.


    That's the stage at which you should have come to us. You should know
    that generally speaking the standard library function WORK. So if you
    are having a problem, it's likely a simple case of misuse.

    Go back and post that code. We'll fix it and you'll be better off all
    around.




    Brian
     
    Default User, Dec 7, 2007
    #7
  8. Guest

    On Dec 7, 2:58 pm, Keith Thompson <> wrote:

    > One problem with that is that strcat() has to scan the target string
    > each time before appending the new string. For a small number of
    > short strings like you have here, it's probably not a big deal, but
    > it's an O(N**2) algorithm for something that can easily be done in
    > O(N).


    strcat() is good enough for what I am doing now

    > If you have a fixed number of strings to append, you might consider
    > sprintf() (though the overhead of processing the format string


    I don't know how many UUID's are in the array so that's why I am
    appending.

    Thank you.
     
    , Dec 7, 2007
    #8
  9. Guest

    On Dec 7, 3:04 pm, "Default User" <> wrote:

    > That's the stage at which you should have come to us. You should know
    > that generally speaking the standard library function WORK. So if you
    > are having a problem, it's likely a simple case of misuse.


    I have got only a few months of C so if there is something wrong, I
    always assume I need to expand my view and search for something else.
    strcpy and strcat expect const char *, and because I am using char * I
    haven't seen too many examples in which you can just pass the char *
    pointer to the function. Most examples deal with char []. Plus I don't
    feel like wasting someone's else time without doing even a shabby
    homework. :)

    I can't make any changes right now. I will have to do it tomorrow.

    Thank you very much.
     
    , Dec 7, 2007
    #9
  10. said:

    > On Dec 7, 3:04 pm, "Default User" <> wrote:
    >
    >> That's the stage at which you should have come to us. You should know
    >> that generally speaking the standard library function WORK. So if you
    >> are having a problem, it's likely a simple case of misuse.

    >
    > I have got only a few months of C so if there is something wrong, I
    > always assume I need to expand my view and search for something else.
    > strcpy and strcat expect const char *,


    For the *source*, not the target. And the const is effectively a promise
    that strcpy and strcat won't change the data you're copying *from* in the
    process of copying that data to the target.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Dec 7, 2007
    #10
  11. Default User Guest

    wrote:

    > On Dec 7, 3:04 pm, "Default User" <> wrote:
    >
    > > That's the stage at which you should have come to us. You should
    > > know that generally speaking the standard library function WORK. So
    > > if you are having a problem, it's likely a simple case of misuse.

    >
    > I have got only a few months of C so if there is something wrong, I
    > always assume I need to expand my view and search for something else.


    That's a puzzling and usually incorrect view. If you are inexperienced
    with a tool, and it doesn't seem to be working, it's not likely that
    you need a different tool. You probably need instruction in proper use
    of the one you have.

    > strcpy and strcat expect const char *, and because I am using char *


    This makes little sense. The signature for strcpy() is:

    char *strcpy(char *destination, const char *source);

    Only the source, which you wouldn't want to change anyway, needs to be
    const qualified. You don't generally WANT to alter a const-qualified
    object. It's bad mojo.


    > I haven't seen too many examples in which you can just pass the char *
    > pointer to the function.


    You see one up there.

    > Most examples deal with char [].


    This doesn't make sense. You can't pass an array into any function. It
    sounds like you need to review the FAQ on arrays and pointers. A
    typical use of strcpy() might be:

    #include <string.h>


    const char *src = "Here's a string!";

    char *dest;

    dest = malloc(strlen(src)+1;

    /* error checking the result of malloc() is vital, but left out here */

    strcpy(dest, src);




    Brian
     
    Default User, Dec 7, 2007
    #11
  12. CBFalconer Guest

    wrote:
    > Keith Thompson <> wrote:
    >
    >> One problem with that is that strcat() has to scan the target
    >> string each time before appending the new string. For a small
    >> number of short strings like you have here, it's probably not a
    >> big deal, but it's an O(N**2) algorithm for something that can
    >> easily be done in O(N).

    >
    > strcat() is good enough for what I am doing now


    I suggest strlcat and strlcpy, which will give you appropriate
    warnings and defaults to avoid overrunning memory allocations.
    See:

    <http://cbfalconer.home.att.net/download/strlcpy.zip>

    for source, usage, documentation, reference to originators, etc.

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Dec 8, 2007
    #12
  13. Guest

    Hello everyone,

    Thanks for all your help. The code is working now.

    Best regards,
    Ovidiu Anghelidi
     
    , Dec 8, 2007
    #13
    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. walala
    Replies:
    3
    Views:
    4,874
    walala
    Sep 18, 2003
  2. Neal Barney

    Partial string loss with sprintf/strcat

    Neal Barney, Jul 22, 2006, in forum: C Programming
    Replies:
    9
    Views:
    400
    Neal Barney
    Aug 3, 2006
  3. Replies:
    3
    Views:
    404
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    731
  5. Andrew Berg
    Replies:
    13
    Views:
    1,359
    Andrew Berg
    Jul 11, 2011
Loading...

Share This Page