如何返回字符串地址然后将其分配给新字符串?

时间:2010-04-12 00:08:49

标签: c pointers string

我有一个函数,我想将指定字符串的地址返回给main函数,并分配一个具有相同地址的新字符串指针,以便新字符串具有旧字符串的内容。

例如:

 unknown_datatype function()
 {
      char *old = "THE STRING";
      return old;
 }

 int main()
 {
      char *snew = "";
      snew = function();
      return 0;
 }

* unknown_datatype意味着我不知道要放在那里......

*如何在不改变main()方法的任何内容的情况下处理此问题

7 个答案:

答案 0 :(得分:3)

通常,您将传递字符数组中第一个元素的地址以及长度,并让函数填充它。

int fillMyString(char *str, int buffer_size)
{
  if(buffer_size > strlen("test"))
  {
    strncpy(str, "test", buffer_size-1);
    str[buffer_size-1] = '\0';
    return strlen(str);
  }

  return 0;
}


//In some function or main
char buffer[1024];
fillMyString(buffer, 1024);
ASSERT(!strcmp(buffer, "test"));

编辑:您提到由于某种原因您需要返回一个char *。在这种情况下,我建议使用malloc在函数内部分配字符串,但确保无论何时调用函数free最终返回值。

答案 1 :(得分:1)

您只需返回char*即可。由于您返回指向字符串文字的指针,因此您最好返回const char*,因为您无法修改字符串文字:

const char* function()

同样,您希望将返回值分配给const char*

const char* snew = 0;
snew = function();

答案 2 :(得分:0)

未知数据类型必须是char*但在这种情况下它不会达到预期效果,因为function()中的变量是局部变量,一旦函数退出并且它们弹出就会消失堆栈。您可以在函数内部使用malloc()调用并返回指向新字符串的指针。当你完成它时,别忘了释放它。

答案 3 :(得分:0)

正如布莱恩指出的那样,在C中做的最惯用的事情是传递一个缓冲区,所以你会这样做:

int give_me_a_string(char* buffer, int buffersize)
{
   const char* result = "Hello world!";
   int requiredbufferlen = strlen(result)+1;
   if ( (buffer==0) || (buffersize<requiredbufferlen) ){
       errno = EINVAL;
       return -1;
   }
   strncpy(buffer,"Hello world!",buffersize);
   buffer[buffersize-1]='\0';
   return 0;
}

int main(int argc, char* argv[])
{
    int buffersize = 256;
    char* buffer = (char*) malloc(buffersize);
    if ( buffer == 0 ){
       printf("Out of memory!\n");
       return 1;
    }
    if ( give_me_a_string(buffer,buffersize) < 0 ){
       printf("Oh my god, there's an error!\n");
       free(buffer);
       return 1;
    }else{
       printf("%s\n",buffer);
    }
    free(buffer);
    return 0;
}

现在,如果你绝对不必传入缓冲区,那么你可以写:

char* give_me_a_string(void)
{
   const char* str="Hello world!";
   int buffersize = strlen(str)+1;
   char* result=(char*) malloc(buffersize);
   if ( result == 0 ){
       return 0;
   }
   strncpy(result,str,buffersize);
   result[buffersize-1]='\0';
   return result;
}

但是,如果您使用上述内容,则必须记住free()结果。但是,我强烈建议你使用前一种方法;当函数返回指针对象时,不清楚谁拥有所有权(即谁负责解除分配字符串)。通过要求调用者传入缓冲区,您可以明确所有权(即调用者拥有缓冲区并且必须自己解除分配)。

您可以使用最后一种解决方案。如果要返回一个常量字符串,那么这是可以接受的;但是,如果你需要计算字符串,这样做会使它不可重入,所以我强烈反对这样做。实际上,即使你返回一个常量字符串,我也会高度建议不要使用这个解决方案,因为那时API无法适应你需要计算字符串的情况。此方法是使用包含结果的共享全局变量,因此它将类似于:

// declaration
char* give_me_a_string(void);

// implementation
char* global_string = "Hello world!";
char* give_me_a_string(void)
{
   return global_string;
}

最后一个解决方案不需要任何解除分配,因为函数本身就是所有者。如果您使用计算字符串执行此操作,它将如下所示:

// declaration
char* give_me_a_string(void);

// implementation
char* global_string = 0;
static void deallocate_global_string()
{
    free(global_string);
    global_string=0;
}

char* give_me_a_string(void)
{
   if ( global_string == 0){
       // allocate global_string
       // ...
       // initialize global_string
       // ...
       // ensure it is eventually freed
       atexit(&deallocate_global_string);
   }
   return global_string;
}

显而易见,如果你这样做,它是不可重入的(它不适用于多个线程),所以这是一个非常非常可怕的想法。如果你被烧了,我只想说,我警告过你。

答案 4 :(得分:0)

好的答案是:由于我无法编辑主要内容(意思是我不能通过任何参数),因此可以采用以下解决方案:

char *function()
{

    char *old;
    old = (char*)malloc(9999);
    strcpy(old,"THE STRING");
    return old;
}

int main()
{
    char *snew = "";
    snew = function();
    return 0;
}

感谢所有回复的人。

答案 5 :(得分:0)

char * function()
{
    char *old = "THE STRING";
    return old;
}

int main()
{
     char *snew = "";
     snew = function();
     return 0;
}

答案 6 :(得分:0)

你的问题和例子相互矛盾。

这是你想要的吗?下面给出两个简单的解决方案。

char * func(char *);

int main()

{

char *newstring="Hey";

newstring = func(newstring);

printf("New string : %s\n", newstring);

}

char * func(char * s)

{

printf("Old string : %s\n", s);

s="Hello";

return(s);

}

或者Y_Y给出的解决方案也没问题,假设您的字符串是在函数调用中创建的。如果你不想使用malloc,下面的解决方案就可以了。

char * func();

int main()

{

char *newstring="";

newstring = func();

printf("New string : %s\n", newstring);

}

char * func()

{

char *s="Hello";

printf("Old string : %s\n", s);

return(s);

}