簡體   English   中英

如何調用 function 作為 strcpy 中的第二個字符串?

[英]How to have a call function as the second string in strcpy?

我需要從 main 調用 function 以確定字符串值。 但是,據我所知,字符串不能采用string_name = call_function()的形式。 字符串的分配必須采用strcpy(str1, str2)的形式,對嗎? 所以我想知道我在用str1作為變量名而str2是另一個strcpy的返回字符串值時我做錯了什么。

到目前為止,這就是我所擁有的。

#include <stdio.h>
#include <string.h>

char *get_name(int num);

char *get_name(int num) {
    char real_name[30];
    
    if (num == 1)
        strcpy(real_name, "Jake Peralta");
    
    return real_name;
}

void main() {
    char name[30];
    int num;
    
    num = 1;
    
    strcpy(name, *get_name(num));
    printf("%s", name);
}

它沒有在我的 output 屏幕上打印任何內容。

我試過的:

  • get_name(num)不使用指針(仍然不起作用)

p/s:這不是實際的代碼。 這只是我正在嘗試做的一個例子,實際代碼更長,我已經確定這部分是錯誤的來源。

您是對的,字符串不能通過return語句作為數組返回。 當您傳遞或返回一個數組時,只使用指向其第一個元素的指針。 因此,function get_name()返回一個指向使用自動存儲在本地定義的數組的指針(也就是在堆棧上)。 這是不正確的,因為該數組一離開 scope 即被丟棄,即:當 function 返回時。

get_name()有幾種方法可以向調用者提供名稱:

  • 您可以傳遞目標數組及其長度:並讓 function 填充數組中的名稱,小心避免超出數組末尾,但確保它具有 null 終止符:

     char *get_name(char *dest, size_t size, int num) { if (num == 1) { snprintf(dest, size, "Jake Peralta"); } else { snprintf(dest, size, "John Doe"); } // return the destination pointer for convenience. return dest; } int main() { char name[30]; int num = 1; get_name(name, sizeof name, num); printf("%s\n", name); return 0; }
  • 您可以在get_name()中分配 memory 並返回指向復制字符串的已分配數組的指針。 當不再使用此 object 時,調用者將負責使用free()它。

     char *get_name(int num) { if (num == 1) { return strdup("Jake Peralta"); } else { return strdup("John Doe"); } } int main() { int num = 1; char *name = get_name(num); printf("%s\n", name); free(name); return 0; }
  • 您可以返回一個常量字符串,但只有在編譯時知道所有名稱時才能這樣做。

     const char *get_name(int num) { if (num == 1) { "Jake Peralta"; } else { "John Doe"; } } int main() { int num = 1; const char *name = get_name(num); printf("%s\n", name); return 0; }

您正在從get_name方法返回real_name的地址,在 function 返回后,go 從 scope 中返回。 而是在堆上分配字符串的 memory 並返回其地址。 此外,調用者需要釋放在堆上分配的字符串 memory 以避免任何 memory 泄漏。

就像您說的那樣,“但是,據我所知,字符串不能采用string_name = call_function()的形式。” 要了解這背后的邏輯,只需查看您的get_name() function:

char *get_name(int num)
{
    char real_name[30];
    
    if (num==1)
        strcpy(real_name,"Jake Peralta");
    
    return real_name;
}

在這里,您嘗試返回 real_name 的起始地址,但是real_name在超出real_name時被銷毀(在這種情況下,當 function 返回時)。 我認為有兩種方法可以解決這個問題。 一種是添加應該保存返回值的字符串作為參數。 在您的情況下,它將是:

void get_name(int num, char *dest)
{
    char real_name[30];
    
    if (num==1)
    {
        strcpy(real_name,"Jake Peralta");
        strcpy(dest, real_name);
    }
}

或者,現在完全避免使用real_name以使 function 更短:

void get_name(int num, char *dest)
{
    if (num==1)
        strcpy(dest, "Jake Peralta");
}

另一種方法是在堆上分配返回值,但我不建議這樣做; 您必須跟蹤每個分配的字符串並最終釋放所有字符串。 不過,在您的情況下,情況如下:

char *get_name(int num, char *dest)
{
    char *real_name = calloc(30, sizeof(char)); // Using calloc to avoid returning an uninitialized string if num is not 1
    if (num==1)
        strcpy(real_name, "Jake Peralta";
    return real_name;
}

順便說一句,我將您的strcpy保留在這里,但可能希望將來避免使用它,因為它可能導致緩沖區溢出。 這是一篇關於為什么不好的有用答案的帖子 事實上,即使strncpy也不是完全安全的(請參閱此處(感謝@chqrlie 提供鏈接))。 @chqrlie 在他自己的答案中使用snprintf提供了一種干凈且安全的替代方案,我建議您使用它。

暫無
暫無

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

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