如何从argv[]中删除memcpy()?
我想从如何从argv[]中删除memcpy()?,c,arrays,string,command-line-arguments,copying,C,Arrays,String,Command Line Arguments,Copying,我想从argv[0]复制字符串,但我不知道如何获取argv[0]的大小 如何做到这一点 int main(int argc, char* argv[]) { char str[20]; if(argc>0) memcpy(str, argv[0], sizeof(argv[0])); } char*argv[]是指针数组(char*),因此sizeof(argv[0])等于sizeof(char*) 您可以使用: 甚至更好的是,您可以使用: 但请注意,argv[0]的
argv[0]
复制字符串,但我不知道如何获取argv[0]
的大小
如何做到这一点
int main(int argc, char* argv[])
{
char str[20];
if(argc>0)
memcpy(str, argv[0], sizeof(argv[0]));
}
char*argv[]
是指针数组(char*
),因此sizeof(argv[0])
等于sizeof(char*)
您可以使用:
甚至更好的是,您可以使用:
但请注意,argv[0]
的长度可能大于目标缓冲区的大小(str
),因此在复制之前,您应该检查argv[0]
的大小
您也可以使用仅复制指定数量的字符,但在这种情况下要非常小心,因为如果
argv[0]
的前20个字符中没有\0
,则必须显式终止字符串。既然argv[0]
是字符串,请使用strlen
#include <string.h>
size_t length = strlen (argv[0]) + 1;
memcpy (str, argv[0], length);
在任何情况下,为了确保您的副本不会溢出,您都应该检查str
的大小是否足够
if (sizeof str >= length)
{
/* Do the copy. */
}
else
{
/* Report an error, or use dynamic allocation. */
}
您需要使用
strlen
。如果要使用sizeof
,则会得到char*
的大小
要复制字符串,您应该使用strcpy或只分配给另一个char*
。更好的方法是,将strncpy
与大小(目标的大小-1)结合使用,以防止缓冲区溢出到str
。-1表示空终止字符(\0
)。别忘了这个角色!如果strlen返回20,问题就变成了。然后它将删除\0
。你也应该阅读,你可以阅读更多关于
或,你可以这样做,我所说的一切都变得毫无意义:
const char*arg1=argv[0]代码>
在这种情况下,这将使strlen变得毫无意义。如果您的Cxx>=C99
然后,您可以通过以下方式执行此操作:
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);
}
我建议您使用指针并根据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);
........
}
如果您的平台支持,您可以使用strdup()
。这使您的代码更简单
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);
........
}
总而言之,因为这里有很多困惑和不好的建议:
从最狭义的角度回答您的问题是,您可以使用(sizeof
返回数据类型的大小(以字节为单位),来计算字符串的长度,对于char*
中的字符串,它(在典型的现代机器上)将是4(在32位系统上)或8(在64位系统上)不管字符串的长度),但是
确保这是你首先需要做的事情。如果不打算更改字符串,则没有理由复制它。如果您确实想要更改它,那么仅当您还想保留旧值时才需要复制它,因为argv
字符串是可变的(根据标准)
如果您不打算更改该变量或不需要旧值,但出于某种原因(可能是可读性),您仍然需要另一个变量,则应将该变量声明为指针而不是数组,并仅为其赋值:
char *str = argv[0];
如果确定要复制字符串,则不应为此使用memcpy
。您应该使用,并且您应该确保新字符串足够大,可以容纳argv[0]
。如果您使用的是C99,您可以轻松做到这一点:
char str[strlen(argv[0]) + 1];
strcpy(str, argv[0]);
如果您使用的是较旧的标准,则需要动态分配内存:
char *str = malloc(strlen(argv[0]) + 1);
strcpy(str, argv[0]);
如果您使用的是POSIX系统,则可以使用以下方法缩短此时间:
如果您使用的是malloc
或strdup
,请记住,使用完后需要手动释放内存
(顺便说一下,在任何情况下,您都不需要检查argc>0
;标准保证argv[0]
是程序名还是零长度字符串(即argv[0][0]
是'\0'
)
如果无法避免使用固定长度的缓冲区,则可以使用如果记住手动nul终止生成的字符串,如果字符串比缓冲区长,则可以截断字符串:
char str[20];
strncpy(str, argv[0], 20); /* or 19, it doesn't matter. */
str[19] = '\0';
我想这就是一切。这里有大量糟糕的建议,我不知道为什么,这个问题不是复杂的火箭科学,而是初级编程
检查argv[0]中是否有参数,但在形式上,始终至少有一个参数传递给main。对argc>0的检查被视为防御性编程,但额外的错误检查从来都不是坏事
在复制未知缓冲区的内容之前,需要检查缓冲区是否溢出
#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);
}
#包括
#包括
int main(int argc,char*argv[])
{
如果(argc==0)
{
//意外错误
}
大小_t len=strlen(argv[0]);
char*str=malloc(len*sizeof(char)+1);
如果(str==NULL)
{
//没有内存,错误
}
strcpy(str,argv[0],len);
...
自由基(str);
}
就这样
- strdup是一个糟糕的建议,因为它不是C标准,因此不可移植。这也是一个完全多余的功能
- strncpy是一个糟糕的建议,它从来没有打算作为strcpy的安全版本。它是一个旧的遗留函数,用于在Dinoon unix系统中处理记录。它比strcpy危险得多,因为很容易忘记空终止。在现代C程序中从来没有理由使用strncpy。不知出于什么原因,有很多程序员被洗脑后使用strncpy来防止缓冲区溢出。不要这样做,正确的方法是在使用strcpy/memcpy之前确保缓冲区足够大
您在此处使用sizeof是错误的。它产生指针的大小argv[0]
strncpy(str,argv[0],20);str[19]=0代码>eve信息
char *str = malloc(strlen(argv[0]) + 1);
strcpy(str, argv[0]);
char *str = strdup(argv[0]);
char str[20];
strncpy(str, argv[0], 20); /* or 19, it doesn't matter. */
str[19] = '\0';
#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);
}