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.
Printable View
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.
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]);
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...?
> 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()
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.
The length you need for the buffer will be strlen(cmd) + strlen of each argv + number of spaces + 1 for the null terminator.
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.
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.
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);
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.
I think in this case I'd rather read and write 1 line of code vs 5.
I believe that snprintf() is less portable, however. I think that it's C99 and not C89.Quote:
Look at snprintf for something a bit more secure.