[英]How do I return a string from a function?
通常我在 PHP 中開發。但是對於一個項目,我必須在 C 中開發一個小程序(在 Windows 上使用 Visual Studio)為了簡化我的代碼,我創建了一個返回字符串的 function(function 比示例中的更復雜)。
最初我有一個警告C4172: returning address of local variable or temporary [duplicate]
我修改了我的 function 不再有這個警告。 它有效。 但是代碼正確嗎...?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// Declaration Function
char* getMyString();
//----------------------------//
// Function getMyString() //
//----------------------------//
char* getMyString()
{
char* response = NULL;
response = (char*)malloc(5 * sizeof(char)); if (response == NULL) exit(EXIT_FAILURE);
strcpy(response, "EFGH");
return response;
}
//--------------------------------------------------//
// Main Program //
//--------------------------------------------------//
int main(int nbArg, char** listeArg)
{
// Initialization
char* myStringFull = malloc(10 * sizeof(char)); if (myStringFull == NULL) return EXIT_FAILURE;
char* myString = NULL;
// Get String with Personnal Function
myString = getMyString();
// Finalization
strcpy(myStringFull, "ABCD");
strcat(myStringFull, myString);
// Display
printf("\n%s\n\n", myStringFull);
// Free Memory
free(myStringFull);
free(myString);
return(EXIT_SUCCESS);
}
如果上面的代碼是正確的,我可以使用下面的代碼來進一步簡化我的代碼......? 如果我可以,它是如何在 memory 中發生的,因為對於最后一個代碼,我無法釋放 function 使用的 memory
int main(int nbArg, char** listeArg)
{
// Initialization
char* myStringFull = malloc(10 * sizeof(char)); if (myStringFull == NULL) return EXIT_FAILURE;
// Finalization
strcpy(myStringFull, "ABCD");
strcat(myStringFull, getMyString());
// Display
printf("\n%s\n\n", myStringFull);
// Free Memory
free(myStringFull);
return(EXIT_SUCCESS);
}
希望我的問題不是太愚蠢,但 PHP 和 C 之間存在巨大、巨大、深淵的差距:)
你所做的是正確的。 但是,您已經注意到這是一項相當多的工作,並且您必須記得在之后釋放分配的 memory。 如果可能的話,我會使用 C++ 這樣你就可以毫無顧慮地返回一個std::string
,就像你在 PHP 和許多其他語言中所做的那樣。
還有其他函數可以幫助您在 C 中創建字符串。例如,復制字符串可以通過 POSIX function strdup()
完成。 您還可以在 GNU 和 BSD 平台上使用asprintf()
。
除了分配 memory,您還可以打印到緩沖區中。 要從 function 執行此操作,您需要將指向緩沖區的指針及其大小傳遞給該 function。例如:
void getMyString(char *buf, size_t size) {
snprintf(buf, size, "EFGH");
}
int main(int argc, char *argv[]) {
char myStringFull[10];
int pos = snprintf(myStringFull, sizeof myStringFull, "ABCD");
getMyString(myStringFull + pos, sizeof myStrinfFull - pos);
printf("%s\n", myStringFull);
}
請注意,上面仍然缺少錯誤檢查; snprintf()
的返回值是在緩沖區足夠大的情況下本應寫入的字符數,或者可能是表示錯誤的負數。
有三種主要方法可以做你想做的事:
static
緩沖區,當 function 未使用時,它有足夠的空間來保存數據char *func(...)
{
static char my_buffer[1000]; /* enough space for the biggest answer */
/* do some calculations to fill my_buffer */
return my_buffer; /* return a pointer to the prepared data */
}
該解決方案的缺點是不可重入,因此如果兩個線程同時嘗試使用它,bot 執行將覆蓋緩沖區,結果將被丟棄。
malloc(3)
分配動態 memory,並返回指向分配的 memory 的指針。這有一個缺點,即一旦不再需要,調用例程負責(並且必須知道) free(3)
ing memory。char *func(...)
{
char *ret_val = malloc(/* enough space to hold the data */);
/* blah blah... */
return ret_val;
}
此解決方案使調用代碼負責或返回 memory,因此容易出錯。
char *func(char *buffer, size_t siz)
{
/* sample code */
snprintf(buffer, siz, "Hello, world\n");
return buffer;
}
/* ... */
void calling_code()
{
char buffer[100];
printf("the string is [%s]\n", func(buffer, sizeof buffer));
}
這種方法賦予調用者分配空間的責任,因此,它不必是動態的,可以是本地空間,因為您將引用及其大小傳遞給它。
你可以 select 最適合你的,但從我的角度來看,更靈活的是最后一個。 試試看吧。
C中的字符串只是一個數組中的字符序列,但是你不能從function中返回一個數組,所以你不能直接返回一個'string'。
C 函數通常做的是將數組(和大小)作為參數傳遞給 function,然后讓 function 將字符串放入數組中以“返回”它。 像fgets
和snprintf
這樣的標准庫函數就是這樣工作的; 他們的第一個和第二個 arguments 是指向數組的指針和該數組的大小。 在你的情況下,這將是這樣的:
char* getMyString(char *buffer, size_t len) {
snprintf(buffer, len, "%s", "EFGH");
return buffer;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.