Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.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
C 复制字符*_C_String - Fatal编程技术网

C 复制字符*

C 复制字符*,c,string,C,String,我有一个函数,它接受char*作为它的一个参数。我需要操纵它,但保留原始字符*不变。基本上,我想创建这个char*的工作副本。看起来这应该很容易,但我真的很挣扎 我第一次(天真的)尝试是创建另一个char*并将其设置为与原始字符相同: char* linkCopy = link; 当然,这不起作用,因为我所做的只是让他们指向同一个地方 我应该使用strncpy来完成这个任务吗 我尝试了以下操作,但它会导致崩溃: char linkCopy[sizeof(link)] = strncpy(lin

我有一个函数,它接受char*作为它的一个参数。我需要操纵它,但保留原始字符*不变。基本上,我想创建这个char*的工作副本。看起来这应该很容易,但我真的很挣扎

我第一次(天真的)尝试是创建另一个char*并将其设置为与原始字符相同:

char* linkCopy = link;
当然,这不起作用,因为我所做的只是让他们指向同一个地方

我应该使用strncpy来完成这个任务吗

我尝试了以下操作,但它会导致崩溃:

char linkCopy[sizeof(link)] = strncpy(linkCopy, link, sizeof(link));
我是不是漏掉了什么明显的


编辑:很抱歉,我试图简化示例,但我在第二个示例中留下了一些较长的变量名。已修复。

您可能需要查看strdup(
manstrdup
)函数:

char *linkCopy = strdup(link);

/* Do some work here */

free(linkCopy);
编辑:既然您需要标准C,就按照其他人指出的那样做:

char *linkCopy = malloc(strlen(link) + 1);
/* Note that strncpy is unnecessary here since you know both the size
 * of the source and destination buffers
 */
strcpy(linkCopy, link);

/* Do some work */

free(linkCopy);

由于strdup()不在ANSI/ISO标准C中,如果它在编译器的运行时中不可用,请继续使用:

/*
**  Portable, public domain strdup() originally by Bob Stout
*/

#include <stdlib.h>
#include <string.h>

char* strdup(const char* str)
{
      char* newstr = (char*) malloc( strlen( str) + 1);

      if (newstr) {
          strcpy( newstr, str);
      }

      return newstr;
}
/*
**可移植的公共域strdup()最初由Bob Stout编写
*/
#包括
#包括
字符*strdup(常量字符*str)
{
char*newstr=(char*)malloc(strlen(str)+1);
if(newstr){
strcpy(newstr,str);
}
返回新闻TR;
}

使用strdup或strndup,如果您知道大小(更安全)

比如:


注:不是C标准

sizeof
会给出指针的大小。这通常是4或8,取决于处理器/编译器,而不是指向的字符串的大小。您可以使用strlen和strcpy:

// +1 because of '\0' at the end
char * copy = malloc(strlen(original) + 1); 
strcpy(copy, original);
...
free(copy); // at the end, free it again.

我已经看到一些答案建议使用strdup,但这是一个posix函数,不是C的一部分。

你的思路是正确的,你需要使用strcpy/strncpy来复制字符串。简单地分配它们只会使它成为一个“别名”,一个指向同一事物的不同名称

第二次尝试中的主要问题是无法以这种方式分配给数组。第二个问题是,您似乎在函数调用中找到了一些新名称,我不知道它们来自何处

你想要的是:

char linkCopy[sizeof(link)];
strncpy(linkCopy, chLastLink, sizeof(link));

但是要小心,sizeof并不总是按照您希望的方式在字符串上工作。使用strlen或strdup。

就像肖恩一样。布莱特说strdup()是处理副本最简单的方法。但是广泛使用的strdup()不是std C。此方法还将复制的字符串保留在堆中

char *linkCopy = strdup(link);

/* Do some work here */

free(linkCopy);
如果您承诺使用堆栈分配的字符串和strncpy(),则需要进行一些更改。你写道:

char linkCopy[sizeof(link)]
这将在堆栈上创建一个指针大小(可能是4字节)的字符数组(也称为字符串)。strncpy()的第三个参数也有同样的问题。你可能想写:

char linkCopy[strlen(link)+1];
strncpy(linkCopy,link,strlen(link)+1);

<>你不说你是否可以用C++代替C,但是如果你可以使用C++和STL,那就更容易了:

std::string newString( original );

使用
newString
就像您使用上面的C样式副本一样,它的语义是相同的。您不需要
释放()
它,它是一个堆栈对象,将被自动处理。

一些答案,包括已接受的答案有点不正确。你不需要复制一个你刚刚打印好的字符串。strcpy不应该在现代程序中使用

正确的做法是使用memcpy


编辑:memcpy在任何体系结构中都很可能更快,strcpy只可能在非常短的字符串中表现得更好,即使它们在这种情况下不相关,也应该避免使用strcpy。

sizeof(link)将返回指针的长度,而不是字符串的长度。是和否。sizeof(数组)如果数组在同一函数中声明,则返回数组的大小;如果数组作为指针传递,则返回指针的大小。这就是为什么我说要小心的原因。请注意,strdup莫名其妙地不是标准的C。请使用以下内容:char*my_strdup(char*str){len=strlen(str)+1;res=malloc(len);if(res!=NULL)memcpy(res,str,len);return res;}(Messy在这里,请随意包含它sean.bright)我喜欢被接受的答案是如何修改3,而这个答案是如何修改8。这个网站上有些东西闻起来不对劲。我不知道有什么例子,但我被要求按照ANSI C标准进行开发,而strdup不是其中的一部分。我很感激你的建议,但我要感谢litb,因为我用他的答案解决了我的问题。添加了一个简单的strdup()实现,这样任何人都可以愉快地使用它。sean.bright,在我为我的答案添加关于strdup的注释之前,我做了一个快速的谷歌搜索,发现至少windows ce没有提供posix函数。我不知道其他人。但是无论如何,如果你有其他保证可用的函数,为什么要使用它呢?这应该是标准C语言的。C语言书可以避免很多陷阱。我喜欢Steven Prata的C primer plus。为什么strndup应该更安全?如果arg to strdup不是以null结尾的,那么可以无限期地读取内存(即直到崩溃)。如果您知道要复制的字符串的长度不能超过X字节,您可以将X传递到strndup,并知道它的读取不会超过X字节。嗯,好吧,尽管我希望应用程序在这种情况下崩溃,因为如果您的字符串不是以null结尾的,您以前就做错了。很可能您使用了strncpy而不是strlcpy在生产环境中,您永远不希望应用程序崩溃。“您不需要strlen'd字符串”-当您不保存strlen:P的结果时,当然可以
std::string newString( original );