Thread: concatenating strings?

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    13

    concatenating strings?

    hey everyone,

    I have some strings in argv that I need to concatenate to another
    string, for example:

    // argv[0] = "1"
    // argv[1] = "2"
    char *cmd = "ls"

    *cmd after concatenating will be "ls 1 2"


    thanks.

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    As you have it now, cmd is a pointer to a string literal which cannot be concatenated to as it's read-only. cmd must be a buffer (character array) or a pointer to dynamically allocated chunk of memory of sufficient size that is writable. After that, you can use sprintf/snprintf or the strcpy/strcat family of functions to get what you want.

    Code:
    char *cmd = malloc(20);  // 20 is just an example size
    strcpy(cmd,"ls ");
    strcat(cmd,argv[0]);
    strcat(cmd," ");
    strcat(cmd,argv[1]);
    Last edited by hk_mp5kpdw; 08-21-2007 at 08:01 AM. Reason: forgot the strcat of the space between argv[0] and argv[1]
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    13
    thanks.
    I'm not sure exactly how much memory to allocate and I'm aware of
    security issues that could occur with that so I looked up strcpy and
    maybe I should use strncpy?

    I thought of something like this, not sure it's ok:

    char *cmd1 = "ls ";

    char *cmd = malloc(20);

    strncpy(cmd, cmd1, sizeof(cmd1));
    strncat(cmd, argv[0], sizeof(argv[0]));
    strcat(cmd, " ");
    strncat(cmd, argv[1], sizeof(argv[1]));
    printf("string is: %s \n", cmd);
    free(cmd1) // this is also required to clear the memory, isn't it?

    thanks again.

    edit: actually I tried that and it doesn't print it very well, also it seems like it prints some junk characters...
    edit2: if I replaced all the strn* functions with the strcpy/strcat functions it works well, where is the problem...?
    Last edited by liri; 08-21-2007 at 08:20 AM. Reason: edit2

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > strncpy(cmd, cmd1, sizeof(cmd1));
    sizeof() is not the thing to use when you're dealing with pointers. It only tells you the size of the pointer, not the length of the string it is pointing to. Try strlen() instead.

    The 3rd parameter to strncpy() should really be something to do with the size of where you're copying to (to prevent buffer overflow). Otherwise, there is no point and you may as well use strcpy() and strcat()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Also, whenever you use strn*(), you have to add the NULL terminator yourself if you want one. This is the reason that your code worked with strcpy()+strcat(), but not with strncpy()+strncat(): strncpy() took a string, say "string", and took sizeof(char *) characters (that is, 4) from it. It didn't add a NULL, as strncpy() is wont to do. So when you printed this string, there was "stri" plus some random characters from memory, until there happened to be a NULL.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The length you need for the buffer will be strlen(cmd) + strlen of each argv + number of spaces + 1 for the null terminator.
    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).

  7. #7
    Registered User
    Join Date
    Aug 2007
    Posts
    13
    Quote Originally Posted by dwks View Post
    Also, whenever you use strn*(), you have to add the NULL terminator yourself if you want one. This is the reason that your code worked with strcpy()+strcat(), but not with strncpy()+strncat(): strncpy() took a string, say "string", and took sizeof(char *) characters (that is, 4) from it. It didn't add a NULL, as strncpy() is wont to do. So when you printed this string, there was "stri" plus some random characters from memory, until there happened to be a NULL.
    how about this:
    strncpy(cmd, cmd1, strlen(cmd1));
    strncat(cmd, argv[0], strlen(argv[0]);
    strcat(cmd, " ");
    strncat(cmd, argv[1], strlen(argv[1]);
    strcat(cmd, "\0"); // this being the NULL terminating string

    printf("string: %s \n", cmd);
    free(cmd);

    this still doesn't work right although better than before.

    thanks.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Try it with just strcpy and strcat for now.

    The "strn" functions are a lot trickier to use when it comes to placing the \0 in the result.

    > strcat(cmd, "\0");
    But strcat() begins by searching for a \0. So if there isn't one your code is broken.
    And if there is one, it does nothing.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Aug 2007
    Posts
    42
    How about:
    sprintf(cmd,"%s%s %s",cmd1, argv[0], argv[1]);

    Look at snprintf for something a bit more secure.

    Or...
    Code:
         char *cmd;
         int      len;
    
         l = strlen(cmd1) + strlen(argv[0]) + strlen(argv[1]);
         cmd = malloc(len+2);
         strcpy(cmd, cmd1);
         strcat(cmd,argv[0]);
         strcat(cmd, " ");
         strcat(cmd, argv[1]);
    
         printf("%s\n", cmd);
         free (cmd);

  10. #10
    Registered User
    Join Date
    Aug 2007
    Posts
    13
    sprintf is good if you're going to use multiple variables to concatenate, but no need to do it if its only one or two concatenations with one or two variables.

  11. #11
    Registered User
    Join Date
    Aug 2007
    Posts
    42
    I think in this case I'd rather read and write 1 line of code vs 5.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Look at snprintf for something a bit more secure.
    I believe that snprintf() is less portable, however. I think that it's C99 and not C89.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Easier way of concatenating a lot of strings?
    By Evenstevens in forum C Programming
    Replies: 2
    Last Post: 05-09-2009, 01:29 PM
  2. Concatenating C style Strings Question
    By bengreenwood in forum C++ Programming
    Replies: 3
    Last Post: 03-19-2009, 03:19 PM
  3. Concatenating 2 strings
    By AngKar in forum C Programming
    Replies: 14
    Last Post: 04-25-2006, 10:51 AM
  4. concatenating more than 2 strings
    By Grunt12 in forum C Programming
    Replies: 3
    Last Post: 11-25-2005, 05:31 PM
  5. Concatenating strings (dynamic array using pointers)
    By Tankndozer in forum C Programming
    Replies: 8
    Last Post: 07-01-2004, 07:27 AM