如何将调用函数作为strcpy中的第二个字符串?
How to have a call function as the second string in strcpy?
我需要从 main 调用一个函数来确定一个字符串值。但是,据我所知,字符串不能是string_name = call_function()
的形式。字符串的赋值必须是 strcpy(str1, str2)
的形式吧?所以我想知道我在用 str1
作为变量名的 strcpy
做错了什么,而 str2
是来自另一个函数的 return 字符串值。
到目前为止,这就是我所拥有的。
#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);
}
它没有在我的输出屏幕上打印任何内容。
我尝试过的:
get_name(num)
不使用指针(仍然不起作用)
p/s:这不是实际代码。这只是我正在尝试做的一个例子,实际代码更长,我已经确定这部分是错误的来源。
您正在 returning get_name
方法中 real_name
的地址,该方法将在函数 return 之后超出范围。而是在堆上分配字符串的内存和 return 它的地址。此外,调用者需要释放在堆上分配的字符串内存以避免任何内存泄漏。
正如您所说,“但是,据我所知,字符串不能采用 string_name = call_function()
的形式。”要了解这背后的逻辑,只需查看您的 get_name()
函数:
char *get_name(int num)
{
char real_name[30];
if (num==1)
strcpy(real_name,"Jake Peralta");
return real_name;
}
这里,你尝试returnreal_name
的起始地址,但是real_name
在超出范围时被销毁(在这种情况下,当函数returns)。我认为有两种方法可以解决这个问题。一种是添加应包含 return 值的字符串作为参数。在您的情况下,它将是:
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
来缩短函数:
void get_name(int num, char *dest)
{
if (num==1)
strcpy(dest, "Jake Peralta");
}
另一种方法是在堆上分配return值,但我不推荐这样做;您将不得不跟踪每个分配的字符串并最终释放所有它们。不过,在您的情况下,情况如下:
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
放在这里了,但以后可能要避免使用它,因为它会导致缓冲区溢出。 Here's a post with useful answers as to why it's bad. In fact, even strncpy
isn't fully safe (See here(归功于提供 link 的@chqrlie)。 @chqrlie 在他自己的回答中使用 snprintf
提供了一种干净安全的替代方法,我建议您使用它。
你是对的,不能通过 return
语句将字符串 return 编辑为数组。当您传递或 return 数组时,仅使用指向其第一个元素的指针。因此,函数 get_name()
return 是一个指向本地定义的数组的指针,具有自动存储(又名 在堆栈上 )。这是不正确的,因为这个数组一旦超出范围就会被丢弃,即:当函数 returns.
get_name()
可以通过多种方式向其调用者提供姓名:
您可以传递目标数组及其长度:并让函数填充数组中的名称,小心避免写入超出数组末尾但确保它有空终止符:
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()
和 return 中分配一个指向您复制字符串的分配数组的指针。调用者有责任在不再使用时使用 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;
}
您可以 return 常量字符串,但只有在编译时已知所有名称时才能这样做。
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;
}
我需要从 main 调用一个函数来确定一个字符串值。但是,据我所知,字符串不能是string_name = call_function()
的形式。字符串的赋值必须是 strcpy(str1, str2)
的形式吧?所以我想知道我在用 str1
作为变量名的 strcpy
做错了什么,而 str2
是来自另一个函数的 return 字符串值。
到目前为止,这就是我所拥有的。
#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);
}
它没有在我的输出屏幕上打印任何内容。
我尝试过的:
get_name(num)
不使用指针(仍然不起作用)
p/s:这不是实际代码。这只是我正在尝试做的一个例子,实际代码更长,我已经确定这部分是错误的来源。
您正在 returning get_name
方法中 real_name
的地址,该方法将在函数 return 之后超出范围。而是在堆上分配字符串的内存和 return 它的地址。此外,调用者需要释放在堆上分配的字符串内存以避免任何内存泄漏。
正如您所说,“但是,据我所知,字符串不能采用 string_name = call_function()
的形式。”要了解这背后的逻辑,只需查看您的 get_name()
函数:
char *get_name(int num)
{
char real_name[30];
if (num==1)
strcpy(real_name,"Jake Peralta");
return real_name;
}
这里,你尝试returnreal_name
的起始地址,但是real_name
在超出范围时被销毁(在这种情况下,当函数returns)。我认为有两种方法可以解决这个问题。一种是添加应包含 return 值的字符串作为参数。在您的情况下,它将是:
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
来缩短函数:
void get_name(int num, char *dest)
{
if (num==1)
strcpy(dest, "Jake Peralta");
}
另一种方法是在堆上分配return值,但我不推荐这样做;您将不得不跟踪每个分配的字符串并最终释放所有它们。不过,在您的情况下,情况如下:
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
放在这里了,但以后可能要避免使用它,因为它会导致缓冲区溢出。 Here's a post with useful answers as to why it's bad. In fact, even strncpy
isn't fully safe (See here(归功于提供 link 的@chqrlie)。 @chqrlie 在他自己的回答中使用 snprintf
提供了一种干净安全的替代方法,我建议您使用它。
你是对的,不能通过 return
语句将字符串 return 编辑为数组。当您传递或 return 数组时,仅使用指向其第一个元素的指针。因此,函数 get_name()
return 是一个指向本地定义的数组的指针,具有自动存储(又名 在堆栈上 )。这是不正确的,因为这个数组一旦超出范围就会被丢弃,即:当函数 returns.
get_name()
可以通过多种方式向其调用者提供姓名:
您可以传递目标数组及其长度:并让函数填充数组中的名称,小心避免写入超出数组末尾但确保它有空终止符:
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()
和 return 中分配一个指向您复制字符串的分配数组的指针。调用者有责任在不再使用时使用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; }
您可以 return 常量字符串,但只有在编译时已知所有名称时才能这样做。
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; }