执行特殊类型的字符串初始化的用C

问题描述:

你知道在C,我们可以初始化字符串变量是这样的:执行特殊类型的字符串初始化的用C

char text[1024] = 
"Hello " 
"World"; 

但如果我有一个返回单词“世界”的功能?

char text[1024] = 
"Hello " 
World(); 

在我看来,这是不可能在C. 请确认。

+10

不,这是不可能的。您只能使用此方法连接字符串文字。 – 2014-11-22 11:59:46

+0

@CoolGuy我需要它到初始化部分。问题已关闭。 – 2014-11-22 12:02:16

+0

@alk嗯什么?你绝对可以... – 2014-11-22 12:02:36

你想要什么是不可能的。

Assigment操作符的L值需要可修改,而数组不是。

从C11-标准:

6.5.16/2

赋值操作员有修改的左值作为它的左操作数。

char text[1024] = "Hello ""World"; 

从C11-标准:

的唯一例外此使用的文字作为R值时初始化期间是

6.7.9/14

字符类型的数组可以通过字符串文字或UTF-8字符串 升al,可选地包含在大括号中。字符串文字的连续字节(包括 ,如果有空间或数组大小未知,则终止空字符)将初始化数组的元素 。

+0

答案已接受。 – 2014-11-24 10:01:44

如果World()的东西,总是返回 “世界”,然后把它定义为一个宏:

#define World "World" 

然后执行:

char text[1024] = 
"Hello " 
World; //Without parentheses 

编辑

字符串连接在你期望的做法是由C预处理器完成的。你实际上是在寻找一个两个字符串的运行时连接,其中c以多种方式执行。最简单的一个是由strcat函数来实现,而应该由函数明确执行初始化:

char text[1024]; 
void init_text() { 
    strcpy(text, "Hello "); 
    strcat(text, World()); //World() defined somewhere else 
} 

使用sprintf备选:

void init_text() { 
    sprintf(text, "Hello %s", World()); 
} 

然后在main函数,调用init_text()开头:

int main() { 
    init_text(); 
    ... 
} 
+0

有关如何使用返回char *初始化程序内部的World()函数的其他想法? – 2014-11-22 12:10:17

+0

我已经更新了我的答案。 – Claudix 2014-11-22 12:39:09

+0

只是为了偏执,如何使用'strncat'和'snprintf'而不是它们的未绑定版本? – LSerni 2014-11-22 16:28:04

标准C中不可能用某些运行时特定的行为来初始化某些东西。因此,标准的便携式方法是通过调用main开头的函数来初始化数据,如answered by Claudix。但是,如果您最近使用了一些GCC编译器(或Clang/LLVM),那么您可以在某些系统(包括Linux和其他POSIX系统)上使用某些constructor attribute on function。所以,你会宣称:

static void init_text(void) __attribute__((constructor)); 

,并定义init_textClaudix's answer没有不必调用它的main:因为它具有constructor属性,它会神奇地main之前,如果出现叫,或在dlopen(3)在一个动态链接的插件或库中。

更便携的技巧可能是让函数返回该文本,以便在第一次调用期间对其进行初始化。因此,不要使用text,您可以拨打get_my_text()(可能通过将#define text get_my_text()放在标题中,但出于可读性原因,我不建议这样做,因此请将text的每次出现替换为get_my_text() ...),并将其定义为:

const char*get_my_text() { 
    static char textbuf[1024]; 
    if (textbuf[0]) { 
     // already initialized, so return it 
     return textbuf; 
    }; 
    snprintf(textbuf, sizeof(textbuf), "Hello %s", World()); 
    return textbuf; 
} 

当心,这样的把戏是不可靠的多线程程序:两个线程可能在同一时间正好运行get_my_text,和你有一个数据race。在多线程应用中,例如, pthread_once

您甚至可以在头文件中将get_my_text定义为static inline函数。

PS始终优先选择snprintf(3)sprintf以避免buffer overflows。还要注意,在标准C++任何static或全球数据与一些给出constructormain之前进行初始化... GCC功能属性故名...