我有两个.c文件,我想编译成可执行文件。刚刚开始学习C,我发现知道如何将文本作为函数之间的参数进行传递是非常棘手的(我发现它在其他所有语言中都非常简单)。
以下是两个文件:
#include <stdio.h>
#include <string.h>
int main(){
char temp[40] = stringCall();
printf("%s",temp);
}
#include <stdio.h>
#include <string.h>
char[] stringCall(){
char toReturn[40] = "Hello, Stack Overflow!";
return toReturn;
}
我经常会遇到类似&#34; Segmentation Failed(core dumped)&#34;或者一样的。我已经做了很多谷歌搜索和惊人的我无法找到解决方案,当然也没有简单的教程&#34;这是如何在函数之间移动文本&#34;。
任何帮助将不胜感激:)
答案 0 :(得分:2)
char toReturn[40] = "Hello, Stack Overflow!";
return toReturn;
这是无效的,你返回一个自动数组,它在函数返回后超出范围 - 这会调用未定义的行为。尝试返回字符串文字本身(它在整个程序中有效):
return "Hello, Stack Overflow!";
或者数组的动态副本:
char toReturn[40] = "Hello, Stack Overflow!";
return strdup(toReturn);
在后一种情况下,您需要free()
调用函数中的字符串。
答案 1 :(得分:1)
你是对的,这在C中并不简单,因为C不能将字符串视为值。
最灵活的方法是:
// Program.c
char temp[40];
if (stringCall(temp, sizeof temp) <= sizeof temp) {
puts(temp);
} else {
// error-handling
puts("My buffer wasn't big enough");
}
// StringReturn.c
int stringCall(char *buf, int size) {
const char toReturn[] = "Hello, Stack Overflow!";
if (sizeof toReturn <= size) {
strcpy(buf, toReturn);
}
return sizeof toReturn;
}
stringCall
不会返回字符串数据,而是将其写入调用者提供的缓冲区size_t
或ssize_t
代替int
。stringCall
在写入之前检查大小。还有其他方法可以在一次调用中执行此操作,所有这些方法都不在C89和C99中,或者在其他方面有缺陷。 C11介绍strcpy_s
。使用你可以使用的工具,这在逻辑上等同于在我上面的代码中自己检查它。永远不要忘记确保nul终结符的空间,它隐藏在每个C字符串的末尾。stringCall
返回想要写入的字节数,即使它没有写任何内容。这意味着缓冲区太小的调用者可以分配更大的调用者并重试。就此而言,调用者可以stringCall(NULL, 0)
来获取大小,而无需尝试任何特定的缓冲区。sizeof
,因为我正在使用编译器已知其大小的数组,但实际上stringCall
可能会使用strlen
或其他方式知道多少它要写的数据。size
的负值。这通常是可以的,因为它们的缓冲区实际上不能具有负大小,因此如果它们的代码已经错误了。但是如果你想确定,或者如果你想帮助你的呼叫者捕获这些错误,你可以写if ((int) sizeof toReturn < size)
或if (size > 0 && sizeof toReturn < size)
。“最灵活”并不总是最好的,但是当函数实际生成文本时,这是很好的,特别是当没有一个简单的方法让调用者提前知道长度而不做一半stringCall
应该为他们做的工作。该界面类似于C99标准函数snprintf
。