tags:

views:

76

answers:

4

Is there a C function that can concatenate all the passed arguments (except the name of the executable) into a char* and return it?

+3  A: 

Why would there be ? Just use strcat in a loop.

Paul R
Strcat in a loop is not so effective, it traverses the first (growing) part of the string for each concatenation.
kaizer.se
That's hardly likely to be a problem with the typical length of command line parameters...
bdonlan
A: 

Something like this? No guarantees that this will compile.

#include <string.h>
#include <stdio.h>

int main(int argc, char ** argv) {
  int i;
  int len = 1;
  char * str;

  for (i = 1; i < argc; i++) {
     len += strlen(argv[i]);
  }

  str = malloc(sizeof(char)*len);
  str[0] = '\0';

  for (i = 1; i < argc; i++) {
     strcat(str, argv[i]);
  }

  //Use str for whatever you want
  printf("My string is %s\n", str);

  free(str);
}
Il-Bhima
You need `str[0] = '\0';` before your `strcat` loop. And your two loops should start at 1 rather than 0 (since he doesn't want the name of the executable in the string). Also it's bad form to cast the result of malloc in C.
Paul R
Thanks for catching that. Fixed. I was always told its bad form not to cast the result of the malloc. Must google about this.
Il-Bhima
You should alloc 1 byte more than the length of the sums of string lengths `str = malloc(len+1);` . Besides the OP wanted only the program paramters, so your loops should start with `i=1` not 0.
tristopia
@tristopia. Thanks for that!
Il-Bhima
@Paul R You were right about the casting. It's strange always remember people telling me to cast the malloc. Must be one of those old myths.
Il-Bhima
Paul mentioned that it's bad form to cast the result of malloc. Besides just looking ugly, it tends to mask the very serious error of using malloc without a prototype, which will break on 64-bit systems. So don't do it.
R..
@Il-Bhima: you need to do this if you call malloc in C++, unfortunately, but there is no need to in C and omitting the unnecessary casts can help avoid masking bugs that the compiler would otherwise have picked up for you.
Paul R
Just for my information, why do you cast the return of malloc ? I think I never saw that.EDIT : Ok, didn't see the preivous replies. What kind of reported bug would it "hide" ?
Shelldon
@Paul R: I think I fixed that. len starts from 1, not 0.
Il-Bhima
A: 

I don't think there's such a function, but if I'm not wrong, you just have to :

  • get the length : len = strlen(argv[1]) + strlen(argv[2]) + ... and check for overflow
  • use malloc : malloc(len + 1) * sizeof(char))
  • set your_copy[0] to '\0'
  • use strcat(your_copy, argv[1]), strcat(your_copy, argv[2])... for each remaining argv[]

EDIT : Oh, the previous answer may be better. ;)

Shelldon
sizeof(*your_copy) is bogus. The definition of sizeof in C is based on char, i.e. sizeof(char) is always 1. By the way, most systems restrict the command line from being gigantic, but you should never add/multiply numbers to pass to malloc unless you've taken care to ensure that the result cannot overflow.
R..
Thanks for this comment, I'll think about it.
Shelldon
+2  A: 

Try that:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    unsigned int i;
    size_t len = 0;
    char *_all_args, *all_args;

    for(i=1; i<argc; i++) {
        len += strlen(argv[i]);
    }

    _all_args = all_args = (char *)malloc(len+argc-1);

    for(i=1; i<argc; i++) {
        memcpy(_all_args, argv[i], strlen(argv[i]));
        _all_args += strlen(argv[i])+1;
        *(_all_args-1) = ' ';
    }
    *(_all_args-1) = 0;

    printf("All %d args: '%s'\n", argc, all_args);

    free(all_args);

    return 0;
}
Johannes Weiß