Reputation: 1637
I want to copy string from argv[0]
but I don't know how to get the size of argv[0]
.
How to do this?
int main(int argc, char* argv[])
{
char str[20];
if(argc>0)
memcpy(str, argv[0], sizeof(argv[0]));
}
Upvotes: 4
Views: 5471
Reputation: 214385
There is such a flood of bad advice here, I have no idea why, this question is not complicated rocket science, but rather beginner level programming.
You check that there is an argument in argv[0], but formally there will always be at least one argument passed to main. The check against argc > 0 is to be regarded as defensive programming, but extra error checks are never bad.
You need to check against buffer overflows before copying the contents of an unknown buffer.
#include <string.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if(argc == 0)
{
// unexpected error
}
size_t len = strlen(argv[0]);
char* str = malloc(len * sizeof(char) + 1);
if(str == NULL)
{
// no memory, error
}
strcpy(str, argv[0], len);
...
free(str);
}
And that's it.
Upvotes: 0
Reputation: 27822
To summarise, because there's a lot of confusion and bad advice here:
The answer to your question in the narrowest sense is that you can find out the length of strings using strlen
(sizeof
returns the size of the data type in bytes, which for strings in char*
, which (on a typical modern machine) will be either 4 (on 32-bit systems) or 8 (on 64-bit systems) regardless of the length of the string), but...
Make sure this is something you need to be doing in the first place. If you don't intend to change the string, there's no reason to copy it. If you do intend to change it, you only need to copy it if you also want to preserve the old value, because the argv
strings are mutable (as per the standard).
If you either don't intend to change it or don't need the old value, but you still want another variable for some reason (readability, presumably), you should declare that variable as a pointer rather than an array and just assign to it:
char *str = argv[0];
If you're sure you do want to copy the string, you should not be using memcpy
for this. You should be using strcpy
, and you should be sure your new string is big enough to hold argv[0]
. If you're using C99, you can do this easily:
char str[strlen(argv[0]) + 1];
strcpy(str, argv[0]);
If you're using an older standard, you will need to allocate memory dynamically:
char *str = malloc(strlen(argv[0]) + 1);
strcpy(str, argv[0]);
If you're on a POSIX system, you can shorten that by using strdup
:
char *str = strdup(argv[0]);
If you're using malloc
or strdup
, remember that you need to free your memory manually when you're done with it.
(You don't need to check if argc > 0
in any case, by the way; the standard guarantees that argv[0]
is either the program name or a zero-length string (that is, argv[0][0]
is '\0'
).)
If you can't get away from using a fixed-length buffer, you can use strncpy
if you remember to nul-terminate the resulting string manually and it's acceptable that your string is truncated if it is longer than the buffer:
char str[20];
strncpy(str, argv[0], 20); /* or 19, it doesn't matter. */
str[19] = '\0';
I think that's everything.
Upvotes: 0
Reputation: 43548
You can use strdup()
if your platform supports it. this makes your code more simple
int main(int argc, char* argv[])
{
char *str = NULL;
if(argc>0) {
str = strdup(argv[0]);
}
.......
// when the str became useless then free it
free(str);
........
}
Upvotes: 1
Reputation: 43548
I suggest to you to use pointer and allocate memory depending of the length of argv[0]
:
int main(int argc, char* argv[])
{
char *str = NULL;
if(argc>0) {
int len = strlen(argv[0])
str = malloc((len+1) * sizeof(char))
memcpy(str, argv[0], (len+1));
}
.......
// when the str became useless then free it
free(str);
........
}
Upvotes: 0
Reputation: 43548
If your Cxx is >= C99
than you can do it in this way:
int main(int argc, char* argv[])
{
int len = (argc>0) ? strlen(argv[0]) : 0;
char str[len+1];
if (argc>0)
memcpy(str, argv[0], len+1);
}
Upvotes: 0
Reputation: 42103
char* argv[]
is an array of pointers (char*
) so sizeof(argv[0])
is equal to sizeof(char*)
.
You could either use strlen
:
memcpy(str, argv[0], strlen(argv[0]) + 1); // +1 because of '\0' at the end
or yet even better you could use strcpy
:
strcpy(str, argv[0]);
but note that the length of the argv[0]
might be greater than the size of your destination buffer (str
) so you should either check the size of argv[0]
before copying it.
You could also use strcnpy
to copy only specified amount of characters, but in that case be very careful, because if there is no \0
in first 20 characters of argv[0]
, you'll have to terminate your string explicitly.
Upvotes: 0
Reputation:
You need to use strlen
. If you were to use sizeof
, then you would get the size of the char*
.
To copy the string, you should use strcpy
or just assign to another char*
. Better yet, use strncpy
in conjunction with a size (the size of the destination - 1) to prevent buffer overflows into str
. The -1 is to account for the null-terminating character (\0
). Don't forget about this character! The problem becomes if strlen returns 20. Then it will drop the \0
. You should also read up on secure use of strcpy and you can read more about strncpy here.
OR, you can do this and it makes everything I said moot:
const char* arg1 = argv[0];
which would make strlen
pointless in this case.
Upvotes: 0
Reputation: 23707
Since argv[0]
is a string, use strlen
.
#include <string.h>
size_t length = strlen (argv[0]) + 1;
memcpy (str, argv[0], length);
By the way, you could also use strcpy
, which is more suitable for strings.
#include <string.h>
strcpy (str, argv[0]);
In every case, in order to make sure that your copy won't overflow, you should check whether the size of str
is sufficient.
if (sizeof str >= length)
{
/* Do the copy. */
}
else
{
/* Report an error, or use dynamic allocation. */
}
Upvotes: 5