簡體   English   中英

對結構中的字符串使用 char* 或 char 數組

[英]Using a char* or a char array for strings within a struct

如果我有一個結構的以下偽代碼,我想在 C 中實現(對於文本編輯器):

STRUCT line
    STRING line_contents
    INT line_length
END

是否有關於如何編寫字符串的最佳實踐? 我看到兩個選項:

struct line {
    char* line_contents;
    size_t line_length;
};

要么...

#define MAX_LINE_LENGTH 1024 // Some arbitrary number

struct line {
    char line_contents[MAX_LINE_LENGTH];
    size_t line_length;
};

第一個的缺點是讓程序員進行手動內存管理,但是,如果結構是鏈表/其他一些高級數據結構的一部分,那么結構很可能就是這種情況。

第二個可能使用太多或太少的內存,它會導致越界錯誤等。

您處理字符串的方式取決於您的用例還是有通用的最佳實踐?

對此沒有通用的最佳實踐。 它主要是浪費的空間與代碼的復雜性。

根據經驗,您可能會考慮典型文檔中的典型行長度 - 在文本編輯器中,1 對 100 字節,因此每行最大“浪費”為 99 字節,在我看來是在現代的、非內存限制的機器上可以接受。 關鍵是:一旦您的用戶想要一行 101 個字符,您就不得不告訴您的用戶有關限制,或者為超長行的情況引入昂貴的解決方法(並且恢復到復雜性)。

但是,您可能要考慮到,面向行的編輯器緩沖區至少已經過時了 30 年。 最常用(並接受,恕我直言)的緩沖區架構是 30 年前引入的 Emacs - 一大塊內存,帶有插入間隙,可前后移動到用戶正在編輯的位置。

您處理字符串的方式取決於您的用例還是有通用的最佳實踐?

沒有“普遍最佳”的做法。 它始終取決於您的特定用例。

但是......你的用例是一個文本編輯器,所以使用具有固定最大行長度的結構對我來說似乎是錯誤的。

但我想展示使用靈活數組成員的第三種方式:

struct line {
    size_t line_length;
    char line_contents[];  <--- Flexible array.
                                malloc determines the size
};

int main() 
{
    char* str = "Hello World";
    size_t len = strlen(str);
    struct line* l = malloc(sizeof *l + len + 1);
                                        \-----/
                                         sizeof the array

    l->line_length = len;
    strcpy(l->line_contents, str);
    printf("Len %zu: %s\n", l->line_length, l->line_contents);
    free(l);
   return 0;
}

通過這種方式,單個malloc可以為字符串分配新節點和內存。

C 庫中常用的解決方案是使用內部 string.h 庫。

C 中的字符串被設計為在末尾帶有一個空終止符,它基本上表示字符串的結束位置。 空終止符是一個 '\\0' 字符。 此處顯示C 字符串方案。

您的代碼可以重新格式化為以下內容。

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

const int MAX_STRING_LENGTH = 256;

int main()
{
   /*+1 for the additional null terminator*/
   char* line = malloc(MAX_STRING_LENGTH + 1);
   strcpy(line, "Hello stack overflow!");

   /*'line' can hold up to 256 byte long strings, but to get the 
   length of "Hello stack overflow!" string that was transfered   
   into 'line' variable, you can use 'strlen()' function as shown 
   below.*/
   printf("Length of 'line' string: %d\n", strlen(line));

   return 0;
}

暫無
暫無

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

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