我有一些函数需要返回一个const char *(以便其他一些函数可以最终使用它)。
我知道如果我的定义如下:
const char* Foo(int n)
{
// Some code
.
.
.
return "string literal, say";
}
那么没有问题。但是我正确地说,如果Foo必须返回一些只能在运行时确定的字符串(取决于参数n,(其中每个n在[0,2 ^ 31-1]中取任何值唯一地确定一个返回字符串) ))然后我必须使用堆(或返回像std :: string这样在内部使用堆的对象)?
std :: string对于我想要完成的事情来说似乎太重了(至少有两个函数必须传递包裹),并且在Foo中分配内存以便被调用者释放并不会让我感到安全。往前走。我不能(轻松地)传递对需要此功能的对象的引用,而不是我认为它是可能的,但宏观技巧是不可能的。
有什么简单的东西我尚未考虑过吗?
感谢所有的答案,我会选择std :: string(我想以一种迂回的方式我要求确认没有办法暗示编译器它应该存储一些char的内容[]在它存储字符串文字的同一个地方)。至于“重量级”(令我惊喜的是,复制它们并不像我想象的那样浪费)这不是最好的方式,或许“不同”会更接近我最初的担忧。
答案 0 :(得分:2)
如果您的意思是您的函数在 n 编译时已知字符串之间进行选择,那么您只需将const char *返回给它们中的任何一个。字符串 literal 在C和C ++中具有静态存储持续时间,这意味着它们在程序的生命周期中存在。因此,将指针返回到一个指针是安全的。
const char* choose_string(int n)
{
switch(n % 4)
{
case 0: return "zero";
case 1: return "one";
case 2: return "two";
case 3: return "three";
}
}
如果你的函数在运行时动态生成一个字符串,那么你必须传入(char *buf, int buf_length)
并将结果写入其中,或者返回std::string
。
答案 1 :(得分:2)
在C ++中,返回std::string
可能是正确答案(正如其他几位已经说过的那样)。
如果您出于某种原因不想使用std::string
(例如,如果您使用C语言进行编程,但是您会以这种方式标记问题),则有几个选项可以“返回”来自函数的字符串。他们都不漂亮。
static
数组(的第一个元素)的指针。这是不灵活的,因为必须在编译时确定最大长度。这也意味着对该函数的连续调用将破坏结果。 {strike> asctime()
<time.h>
中定义的<ctime>
函数执行此操作。 (我曾经写过一个循环通过静态数组数组元素的函数,因此6次连续调用不会破坏以前的结果,但是第7次会结果。这可能是过度杀伤。)现在您知道为什么C ++提供像std::string
这样的库功能来处理所有这些内容。
顺便说一下,短语“变量字符串文字”并没有多大意义。如果某事是文字,那就不是变数。可能“变量字符串”就是你的意思。
答案 2 :(得分:1)
最简单的解决方案可能是返回std::string
。
如果你想避免使用std :: string,另一种方法是让调用者将char[]
缓冲区传递给函数。您可能还希望提供一个函数,该函数可以告诉调用者需要多大的缓冲区,除非静态地知道上限。
答案 3 :(得分:1)
使用std::string
,但如果你真的想... C编程中使用的常见模式是返回最终结果的大小,分配缓冲区,并调用该函数两次。 (我为C风格道歉,你想要一个C解决方案,我给出一个C解决方案:P)
size_t Foo(int n, char* buff, size_t buffSize)
{
if (buff)
{
// check if buffSize is large enough if so fill
}
// calculate final string size and return
return stringSize;
}
size_t size = Foo(x, NULL, 0); // find the size of the result
char* string = malloc(size); // allocate
Foo(x,string, size); // fill the buffer
答案 4 :(得分:0)
(穿石棉套装)
考虑只是泄漏内存。
const char* Foo(int n)
{
static std::unordered_map<int, const char*> cache;
if (!cache[n])
{
// Generate cache[n]
}
return cache[n];
}
是的,这会泄漏内存。最多2 ^ 32个字符串值得。但是如果你有实际的字符串文字,你总是在内存中有所有 2 ^ 32个字符串(显然需要64位构建 - 只需要\ 0单独占用4GB !)