簡體   English   中英

如何從 function 返回一個字符串?

[英]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()的返回值是在緩沖區足夠大的情況下本應寫入的字符數,或者可能是表示錯誤的負數。

有三種主要方法可以做你想做的事:

  1. 您可以只聲明一個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 執行將覆蓋緩沖區,結果將被丟棄。

  1. 您可以使用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,因此容易出錯。

  1. 您可以從調用代碼傳遞一個本地的、已經分配的緩沖區,以及它的大小。 您可以使用該緩沖區來保存請求的數據,然后返回一個指向字符串開始位置的有效指針(我也不必從緩沖區的開頭開始)
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 將字符串放入數組中以“返回”它。 fgetssnprintf這樣的標准庫函數就是這樣工作的; 他們的第一個和第二個 arguments 是指向數組的指針和該數組的大小。 在你的情況下,這將是這樣的:

char* getMyString(char *buffer, size_t len) {
    snprintf(buffer, len, "%s", "EFGH");
    return buffer;
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM