Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从argv[]中删除memcpy()?_C_Arrays_String_Command Line Arguments_Copying - Fatal编程技术网

如何从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]=0eve信息
    
    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);
    }