我有一个函数,我想将指定字符串的地址返回给main函数,并分配一个具有相同地址的新字符串指针,以便新字符串具有旧字符串的内容。
例如:
unknown_datatype function()
{
char *old = "THE STRING";
return old;
}
int main()
{
char *snew = "";
snew = function();
return 0;
}
* unknown_datatype意味着我不知道要放在那里......
*如何在不改变main()方法的任何内容的情况下处理此问题
答案 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);
}