[英]How to have a call function as the second string in strcpy?
我需要从 main 调用 function 以确定字符串值。 但是,据我所知,字符串不能采用string_name = call_function()
的形式。 字符串的分配必须采用strcpy(str1, str2)
的形式,对吗? 所以我想知道我在用str1
作为变量名而str2
是另一个strcpy
的返回字符串值时我做错了什么。
到目前为止,这就是我所拥有的。
#include <stdio.h>
#include <string.h>
char *get_name(int num);
char *get_name(int num) {
char real_name[30];
if (num == 1)
strcpy(real_name, "Jake Peralta");
return real_name;
}
void main() {
char name[30];
int num;
num = 1;
strcpy(name, *get_name(num));
printf("%s", name);
}
它没有在我的 output 屏幕上打印任何内容。
我试过的:
get_name(num)
不使用指针(仍然不起作用)p/s:这不是实际的代码。 这只是我正在尝试做的一个例子,实际代码更长,我已经确定这部分是错误的来源。
您是对的,字符串不能通过return
语句作为数组返回。 当您传递或返回一个数组时,只使用指向其第一个元素的指针。 因此,function get_name()
返回一个指向使用自动存储在本地定义的数组的指针(也就是在堆栈上)。 这是不正确的,因为该数组一离开 scope 即被丢弃,即:当 function 返回时。
get_name()
有几种方法可以向调用者提供名称:
您可以传递目标数组及其长度:并让 function 填充数组中的名称,小心避免超出数组末尾,但确保它具有 null 终止符:
char *get_name(char *dest, size_t size, int num) { if (num == 1) { snprintf(dest, size, "Jake Peralta"); } else { snprintf(dest, size, "John Doe"); } // return the destination pointer for convenience. return dest; } int main() { char name[30]; int num = 1; get_name(name, sizeof name, num); printf("%s\n", name); return 0; }
您可以在get_name()
中分配 memory 并返回指向复制字符串的已分配数组的指针。 当不再使用此 object 时,调用者将负责使用free()
它。
char *get_name(int num) { if (num == 1) { return strdup("Jake Peralta"); } else { return strdup("John Doe"); } } int main() { int num = 1; char *name = get_name(num); printf("%s\n", name); free(name); return 0; }
您可以返回一个常量字符串,但只有在编译时知道所有名称时才能这样做。
const char *get_name(int num) { if (num == 1) { "Jake Peralta"; } else { "John Doe"; } } int main() { int num = 1; const char *name = get_name(num); printf("%s\n", name); return 0; }
您正在从get_name
方法返回real_name
的地址,在 function 返回后,go 从 scope 中返回。 而是在堆上分配字符串的 memory 并返回其地址。 此外,调用者需要释放在堆上分配的字符串 memory 以避免任何 memory 泄漏。
就像您说的那样,“但是,据我所知,字符串不能采用string_name = call_function()
的形式。” 要了解这背后的逻辑,只需查看您的get_name()
function:
char *get_name(int num)
{
char real_name[30];
if (num==1)
strcpy(real_name,"Jake Peralta");
return real_name;
}
在这里,您尝试返回 real_name 的起始地址,但是real_name
在超出real_name
时被销毁(在这种情况下,当 function 返回时)。 我认为有两种方法可以解决这个问题。 一种是添加应该保存返回值的字符串作为参数。 在您的情况下,它将是:
void get_name(int num, char *dest)
{
char real_name[30];
if (num==1)
{
strcpy(real_name,"Jake Peralta");
strcpy(dest, real_name);
}
}
或者,现在完全避免使用real_name
以使 function 更短:
void get_name(int num, char *dest)
{
if (num==1)
strcpy(dest, "Jake Peralta");
}
另一种方法是在堆上分配返回值,但我不建议这样做; 您必须跟踪每个分配的字符串并最终释放所有字符串。 不过,在您的情况下,情况如下:
char *get_name(int num, char *dest)
{
char *real_name = calloc(30, sizeof(char)); // Using calloc to avoid returning an uninitialized string if num is not 1
if (num==1)
strcpy(real_name, "Jake Peralta";
return real_name;
}
顺便说一句,我将您的strcpy
保留在这里,但可能希望将来避免使用它,因为它可能导致缓冲区溢出。 这是一篇关于为什么不好的有用答案的帖子。 事实上,即使strncpy
也不是完全安全的(请参阅此处(感谢@chqrlie 提供链接))。 @chqrlie 在他自己的答案中使用snprintf
提供了一种干净且安全的替代方案,我建议您使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.