在C

时间:2016-02-22 04:12:03

标签: c string pointers

我得到一个指向作为函数参数传递的字符串的指针,我需要更改字符串中的几个字符。我将字符串复制到char数组并编辑我需要的内容,但我需要将指向的原始字符串更改为刚刚创建的新char []。

该函数必须返回void,并且因为传递的指针只是main中的一个指针的副本,将其设置为指向新的char []不会做任何事情,因为它只会被删除函数结束,所以我需要实际更改指向的字符串。

*str = &newstr[0]

这给了我编译器错误:赋值在没有强制转换的情况下从指针生成整数。

*str = newstr

当我运行程序时,这就是segfaulting。

这是完整的功能:

void replace(char* str, char toReplace, char replaceWith) {
  int strLen = strlen(src);
  char newstr[strLen];
  int i;
  for (i = 0; i < strLen; i++) {
    if (str[i] == toReplace)
      newstr[i] = replaceWith;
    else 
      newstr[i] = str[i];
  }
  // How to change the value of the string being pointed to by *str to now be newstr?
}

2 个答案:

答案 0 :(得分:1)

在消化了您的问题的所有评论之后,我已经了解到您尝试以下列方式调用您的功能:

char * str = "string literal";  /* compiler should have warned you about assigning
                                   string literal to non-const pointer.            */
replace( str, 'i', 'u' );
printf( "%s\n", str );

现在,问题是任何尝试修改str指向未定义行为的内存。

您尝试解决方案是尝试更改函数内部的实际指针。但要这样做,您的replace函数需要接受char**,然后分配新内存。在这种情况下,这不是一个好方法。你真的只需要就地修改字符串:

void replace(char* str, char toReplace, char replaceWith)
{
    while( *str )
    {
        if( *str == toReplace ) *str = replaceWith;
        str++;
    }
}

如何处理字符串文字?嗯,解决方案很简单。制作一个数组:

char str[] = "string literal";
replace( str, 'i', 'u' );
printf( "%s\n", str );

答案 1 :(得分:0)

  

如何将* str指向的字符串的值更改为now   是newstr?

由于({1)将str作为char *s (2)传递给函数的方式,因为您宣布{{1} }作为newstr中的局部变量。 (可能是由于您发布的有限代码部分无法确定的一系列其他原因)

当您将指针传递给函数时,该函数会接收指针的 copy 非常非常不同的内存地址。换句话说,当您在函数参数列表中声明参数replace时,会创建一个新指针。 (它仍然指向char *str中传递的任何内容,但它的变量地址与调用函数中的原始指针地址非常不同 - 所以你对str的地址所做的任何事都不会 反映在调用函数中。)如果要为函数中的指针指定新地址,则必须从调用者传递原始地址。例如

str

然后在您的调用例程中调用它:

void replace(char **str, char toReplace, char replaceWith)

(作为一种风格:不要在C中使用replace (&origPtr, char toReplace, char replaceWith) 变量,CamelCase是正确的)

最后,由于退出函数camelcase时,newstr的地址将被销毁,因此将replace的地址指定给newstr的唯一选择是(1) )将*str声明为newstr,或(2)动态分配static(例如newstr。然后,您可以将char *newstr = malloc (sizeof *newstr * strLen + 1);的值指定给newstr例如:

str

注意: void replace(char **str, char toReplace, char replaceWith) { int strLen = strlen(*str); int i; char *newstr = malloc (sizeof *newstr * strLen + 1); if (!newstr) { fprintf (stderr, "error: virtual memory exhausted.\n"); exit (EXIT_FAILURE); } for (i = 0; i < strLen; i++) { if ((*str)[i] == toReplace) newstr[i] = replaceWith; else newstr[i] = (*str)[i]; } newstr[strLen] = 0; /* nul-terminate (or use calloc to allocate) */ free (*str); /* MUST have been dynamically allocated in caller */ *str = newstr; } 一定不能在调用函数中静态声明,并且你必须str它所指向的内存块,否则你将创建一个内存通过将起始地址覆盖到它最初指向的内存块来泄漏 - 使得无法释放原始块。)

所有这些原因是更好地通过更改freetoReplace个字符来解决此问题的原因(假设replaceWith是一个数组而不是 string-literal ),或传递一个额外的数组来填充替换作为参数(或作为指向分配的指针 - 或返回指向新分配的块的指针包含新字符串的内存)。

如果您还有其他问题,请与我们联系。