如何从argv [] memcpy()?

时间:2013-03-27 13:08:52

标签: 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]));
}

8 个答案:

答案 0 :(得分:6)

由于argv[0]是一个字符串,请使用strlen

#include <string.h>

size_t length = strlen (argv[0]) + 1;

memcpy (str, argv[0], length);

顺便说一句,你也可以使用strcpy,它更适合字符串

#include <string.h>

strcpy (str, argv[0]);

在每种情况下,为了确保您的副本不会溢出,您应该检查str的大小是否足够。

if (sizeof str >= length)
{
  /* Do the copy. */
}
else
{
  /* Report an error, or use dynamic allocation. */
}

答案 1 :(得分:1)

如果您的平台支持,您可以使用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);
  ........
}

答案 2 :(得分:0)

char* argv[]是一系列指针(char*),因此sizeof(argv[0])等于sizeof(char*)

您可以使用strlen

memcpy(str, argv[0], strlen(argv[0]) + 1);  // +1 because of '\0' at the end

或更好的是你可以使用strcpy

strcpy(str, argv[0]);

但请注意argv[0]的长度可能大于目标缓冲区的大小(str),因此您应该在复制之前检查argv[0]的大小。< / p>

您还可以使用strcnpy仅复制指定数量的字符,但在这种情况下要非常小心,因为如果\0的前20个字符中没有argv[0],则我必须明确地终止你的字符串。

答案 3 :(得分:0)

您需要使用strlen。如果您使用sizeof,那么您将获得char*的大小。

要复制字符串,您应使用strcpy或仅指定给其他char*。更好的是,将strncpy与大小(目标大小 - 1)结合使用,以防止缓冲区溢出到str。 -1表示空终止字符(\0)。不要忘记这个角色!如果strlen返回20,问题就出现了。然后它将丢弃\0。您还应该阅读secure use of strcpy,然后了解有关strncpy here的更多信息。

,你可以做到这一点,它让我说的一切都没有意义:

const char* arg1 = argv[0];

这会使strlen在这种情况下毫无意义。

答案 4 :(得分:0)

如果你的Cxx是&gt; = 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);
}

答案 5 :(得分:0)

我建议您根据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);
  ........
}

答案 6 :(得分:0)

总结一下,因为这里有很多混乱和不好的建议:

在最狭义的意义上,你的问题的答案是你可以使用strlen找出字符串的长度(sizeof以字节为单位返回数据类型的大小,strcpy中的字符串1}},(在典型的现代机器上)将是4(在32位系统上)或8(在64位系统上),无论字符串的长度如何),。 ..

  1. 确保这是您首先需要做的事情。如果您不打算更改字符串,则没有理由复制它。如果你打算改变它,你只需要复制它,如果你还想保留旧值,因为char*字符串是可变的(根据标准)。

    如果您不打算更改它或不需要旧值,但由于某种原因(可能性,可能)仍然需要另一个变量,您应该将该变量声明为指针而不是数组只需分配给它:

    argv
  2. 如果您确定要复制字符串,则应该使用char *str = argv[0]; 。您应该使用strdup,并且您应确保新字符串足以容纳memcpy 。如果您使用的是C99,则可以轻松完成:

    argv[0]

    如果您使用的是较旧的标准,则需要动态分配内存:

    char str[strlen(argv[0]) + 1];
    strcpy(str, argv[0]);
    

    如果您使用的是POSIX系统,可以使用strncpy来缩短它:

    char *str = malloc(strlen(argv[0]) + 1);
    strcpy(str, argv[0]);
    

    如果您使用的是char *str = strdup(argv[0]); malloc,请记住在完成操作后需要手动释放内存。

    (顺便说一下,你不需要检查strdup是否正确;标准保证argc > 0是程序名或零长度字符串(即{ {1}}是argv[0])。)

  3. 如果你无法使用固定长度的缓冲区,你可以使用{{3}} 如果你记得手动终止结果字符串并且如果字符串比缓冲区长,则可以截断它:

    argv[0][0]
  4. 我认为这就是一切。

答案 7 :(得分:0)

这里有如此大量的不好建议,我不知道为什么,这个问题并不是复杂的火箭科学,而是初学者级别的编程。

你检查argv [0]中是否有参数,但是正式地总是会有至少一个参数传递给main。检查argc&gt; 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);
}

就是这样。


  • strdup是不好的建议,因为它不是C标准,因此不便携。它也是一个完全多余的功能。
  • strncpy是一个糟糕的建议,它从来没有打算作为strcpy的安全版本。它是处理恐龙unix系统记录的旧遗留功能。它比strcpy更危险,因为很容易忘记null终止。在现代C程序中使用strncpy是没有理由的。由于某种原因未知,有很多程序员被洗脑使用strncpy作为防止缓冲区溢出的防范。不要这样做,正确的方法是在使用strcpy / memcpy之前确保缓冲区足够大。