Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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_C Strings - Fatal编程技术网

将c字符串逐字符复制到动态字符*

将c字符串逐字符复制到动态字符*,c,c-strings,C,C Strings,我有一个const char*字符串,我想将该字符串逐个字符复制到动态'char* const char *constStr = "Hello world"; char *str = (char*) malloc(strlen(constStr)+1); while(*constStr){ *str = *constStr; constStr++; str++; } printf("%s", str); free(str); 问题是前面的代码只将constStr的每个字符复制

我有一个
const char*
字符串,我想将该字符串逐个字符复制到动态'char*

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr)+1);
while(*constStr){
   *str = *constStr;
   constStr++;
   str++;
}
printf("%s", str);
free(str);

问题是前面的代码只将
constStr
的每个字符复制到
str
的第一个索引中。我不知道为什么?

正如其他人所指出的,在每次迭代中,您都在递增
str
指针,因此您总是打印字符串的结尾

您可以在不增加指针的情况下迭代每个字符。以下代码适用于我:

const char *constStr = "Hello world";
int len = strlen(constStr);
char *str = (char *) malloc(len + 1);
int i;
for (i = 0; i <= len; ++i) {
    str[i] = constStr[i];
}
printf("%s", str);
free(str);
const char*constStr=“你好世界”;
int len=strlen(constStr);
char*str=(char*)malloc(len+1);
int i;
对于(i=0;i,这里是“经典”字符串复制解决方案:

const char *constStr = "Hello world";
char *str = malloc(strlen(constStr) + 1), *p = str;
/* Do not forget to check if str!=NULL !*/
while((*p++ = *constStr++));
puts(str);

是的,您没有null终止字符串。这是主要问题。更清楚地说,问题不在于您没有nul终止字符串,而在于您在需要指向nul终止字符数组的指针时使用它们。但即使您这样做,代码中也存在大量问题

您分配了内存并强制转换了
malloc
的返回值,这是不必要的。
void*
char*
的转换是隐式完成的

malloc可能无法为请求提供服务,它可能返回空指针。这一点很重要 检查此项以防止以后尝试取消引用空指针

然后开始复制-复制了NUL终止字符以外的所有字符。然后将其传递给
printf
%s
格式说明符,该说明符需要指向以null结尾的字符数组的指针。这是未定义的行为

str
中的一个位置未初始化-注意访问未初始化的值可能导致未定义的行为

还有另一个问题,来自标准§

free
函数使
ptr
指向的空间被释放,也就是说,可供进一步分配。如果
ptr
是空指针,则不会发生任何操作。否则,如果参数与内存管理函数先前返回的指针不匹配,或者该空间已被调用free或realloc,行为未定义

是的,这里的情况也是这样吗?不是。当您调用
free(str)
str
时,它没有指向
malloc
返回的动态分配内存。这也是未定义的行为

解决方法总是保留一个指针,该指针存储分配的块的地址。其他答案已经显示了它们(不重复它们-两者都提供了一个很好的解决方案)

您也可以使用
strdup
strcpy
,即使您现在不需要它们,也要习惯它们。了解它们会有所帮助。是的
strdup
不是标准的一部分,它是POSIX标准的一部分

例如:

const char *constStr = "Hello world";
char *str = malloc(strlen(constStr)+1);
if( !str ){
    perror("malloc");
    exit(EXIT_FAILURE);
}
char *sstr = str;
while(*constStr){
   *str = *constStr;
   constStr++;
   str++;
}
*str = 0;
printf("%s", sstr);
free(sstr);
问题是前面的代码只复制了 constStr只指向str的第一个索引。我不知道为什么

  • 使用索引变量
  • 不要忘记终止“\0”,因为很有可能出现分段错误

  • 它复制整个字符串,但是,当您打印它时,您只打印字符串的结尾!因为现在
    str
    指向字符串的结尾。(实际上它正好指向结尾之后)是否有原因
    strdup
    strcpy
    不符合您的需要?您没有复制字符串终止符,即
    NUL
    字符。另外,
    str
    现在位于新字符串的末尾。您还可能会因
    free(str)而发生SegFault
    由于
    str
    不再指向
    malloc
    返回的内存块的开头。回想一下您在动态分配内存方面的两项职责(1)始终保留指向
    malloc
    返回的内存块开头的指针,因此(2)当不再需要时,它可以被释放。这不会使新字符串终止为null。如果您要调用
    strlen
    两次,您最好保存长度,以便知道在哪里终止新字符串。@RetiredInja谢谢!我根据您的建议更新了我的代码。@pgngp:谢谢您的回答,您的答案是正确的。@哦。如果你不明白我提到的任何部分,请告诉我。我会尽量说得更清楚。谢谢你的努力,我对此表示感谢,但因为你知道这里大多数成员的母语不是英语,所以最好用一个简短的例子来解释这个问题。@LionKing--对每个人来说,bu与简短的不完整答案相比,我们中的许多人并不喜欢完整的答案。海报通常不会注意到那些乍一看似乎不会造成问题的重大问题。记住,这样做的主要目的不是为你回答问题,而是提供一个可搜索的准确信息库。我对这个答案的唯一质疑是very minor:
    strdup()
    是POSIX,并且广泛可用,但不是标准的C。@DavidBowling.:是的……添加了它。Thanks@LionKing.当前位置发生了很多事情..怎么可能这么短?我也可以发布一个简短的答案…但这并不能解释一切。那会有帮助吗?