我意识到以下将无法正常工作,但有没有相当的?全局变量在主要连接?
const char *foo = "foo";
static char *end = sprintf ("%s_bar", foo);
我想要做的是连接字符串,然后使该连接字符串一个静态变量,使之成为一个全局变量。另外我喜欢不必将内存分配给字符。我需要这个去main()
因为我需要使用一个函数(sprintf)来合并两个字符串。
我意识到以下将无法正常工作,但有没有相当的?全局变量在主要连接?
const char *foo = "foo";
static char *end = sprintf ("%s_bar", foo);
我想要做的是连接字符串,然后使该连接字符串一个静态变量,使之成为一个全局变量。另外我喜欢不必将内存分配给字符。我需要这个去main()
因为我需要使用一个函数(sprintf)来合并两个字符串。
sprintf
被声明为int sprintf(char * str,const char format,...); char* str
是写入输出的缓冲区,然而恶意用户可能会将该缓冲区放在比该缓冲区的大小更多的地方,因此也可以使用snprintf
,其中包含一个包含输出缓冲区大小的参数,因此缓冲区溢出不会发生。你应该注意到它返回的是写入的字节数,因此你不能将它分配给char或char []。
const char* foo = "foo";
static char end[BUFSIZE];
snprintf(end, BUFSIZE, ""%s_bar", foo);
我更喜欢使用snprintf
因为它并不那么容易导致缓冲区溢出这是一个安全的错误。现在它可以打印BUFSIZ
字符到end
如果snprintf返回strlen(“s_bar”)+ strlen(“foo”);则可以查看连接是否成功。
什么你也可以做的是:
char end[BUFSIZE] = "foo_";
strncat(end, "_bar", BUFSIZ);
这也许是更多你喜欢什么。
你想写'char end [BUFSIZE] ...'? – alk
@alk哎呀你编辑得挺对的;-) – hetepeperfan
从表面上看,可以按如下修改代码:
#define FOO_INITIALIZER "foo"
const char *foo = FOO_INITIALIZER;
static char *end = FOO_INITIALIZER "_bar";
我不知道多少给你买了,但它应该编译和避免串的重复。它使用相邻的字符串连接,这在C89及更高版本中是标准的(但不是在标准的编译器中)。
我想你可以用字符串化操作符来完成它。
#define STR_CONCAT(x, y) #x#y
static char *end = STR_CONCAT(foo, _bar);
int main(void)
{
printf("%s", end); // prints out "foo_bar"
getchar();
return 0;
}
你不能使用'##'连接字符串(或者,至少你的编译器不应该让你这么做) - 而且你不需要这样做因为字符串连接会自动发生。 –
@JonathanLeffler:这实际上已经过测试(MS VS2010)。所以我可以做到。 :) – abelenky
你需要得到一个符合标准的工作编译器! GCC说'cat.c:3:1:错误:粘贴“”foo“”和“”_bar“”没有提供有效的预处理标记。 –
您可以在宏中使用'##'运算符 –
@alk - 什么时候有变量?所以“_bar”实际上是一个变量条... – user983223
请注意,在64位机器上,您已经分配了12个字节来支持'foo':指针为8个字节,字符串为4个字节。如果你得到了一些工作,你已经有16个字节分配给'end':指针为8个字节,字符串为8个字节。您必须以某种方式指定字符串的8个字节。请注意,使用'const char foo [] =“foo”;'只为字符串分配4个字节,而'const char end [] =“foo_bar”;'仅为字符串分配8个字节。 –