4

我想从中复制字符串,argv[0]但我不知道如何获取argv[0].

这个怎么做?

int main(int argc, char* argv[])
{
  char str[20];
  if(argc>0)
      memcpy(str, argv[0], sizeof(argv[0]));
}
4

8 回答 8

5

因为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. */
}
于 2013-03-27T13:12:14.033 回答
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);
  ........
}
于 2013-03-27T14:34:13.303 回答
0

你需要使用strlen. 如果您要使用sizeof,那么您将获得char*.

要复制字符串,您应该使用strcpy或分配给另一个char*. 更好的是,strncpy与大小(目标大小 - 1)结合使用,以防止缓冲区溢出到str. -1 用于说明空终止字符 ( \0)。不要忘记这个角色!如果 strlen 返回 20,问题就变成了。然后它将删除\0. 您还应该阅读strcpy 的安全使用,并且可以在此处阅读有关 strncpy的更多信息。

或者,你可以这样做,它使我所说的一切变得毫无意义:

const char* arg1 = argv[0];

strlen在这种情况下,这将毫无意义。

于 2013-03-27T13:13:14.307 回答
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);
}

就是这样。


  • strdup 是一个不好的建议,因为它不是 C 标准,因此不可移植。这也是一个完全多余的功能。
  • strncpy 是个坏建议,它从来没有打算作为 strcpy 的安全版本。它是恐龙 unix 系统中用于处理记录的旧功能。它比 strcpy 危险得多,因为它很容易忘记空终止。从来没有理由在现代 C 程序中使用 strncpy。由于某种未知的原因,有很多程序员被洗脑而使用 strncpy 作为防止缓冲区溢出的保护措施。不要这样做,正确的做法是在使用strcpy/memcpy之前确保缓冲区足够大。
于 2013-03-28T07:52:03.353 回答
0

总而言之,因为这里有很多混乱和不好的建议:

从最狭义的角度来看,您的问题的答案是,您可以使用strlen(sizeof返回数据类型的大小(以字节为单位),对于 in 中的字符串char*,它(在典型的现代机器上)将是 4(在32 位系统)或 8(在 64 位系统上),无论字符串的长度如何),但是...

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

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

    char *str = argv[0];
    
  2. 如果您确定确实要复制字符串,则不应使用memcpy。您应该使用strcpy,并且您应该确保您的新字符串足够大以容纳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 系统,则可以使用以下方法缩短它strdup

    char *str = strdup(argv[0]);
    

    如果您使用mallocor strdup,请记住,您需要在完成后手动释放内存。

    (顺便说一句,您不需要检查是否argc > 0在任何情况下;标准保证argv[0]是程序名称或零长度字符串(即argv[0][0]is '\0')。)

  3. 如果您无法摆脱使用固定长度的缓冲区,您可以使用如果您记得手动终止生成的字符串并且如果字符串比缓冲区长,则可以截断您的字符串:strncpy

    char str[20];
    strncpy(str, argv[0], 20); /* or 19, it doesn't matter. */
    str[19] = '\0';
    

我认为这就是一切。

于 2013-03-27T14:47:37.040 回答
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]在复制之前检查 的大小。

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

于 2013-03-27T13:12:08.290 回答
0

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);
}
于 2013-03-27T13:49:18.023 回答
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);
  ........
}
于 2013-03-27T14:32:49.327 回答