我意識到以下將無法正常工作,但有沒有相當的?全局變量在主要連接?
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個字節。 –