2010-11-22 68 views
3

我需要一個任務做的是:龜etc():讀取和存儲未知長度的字符串

  • 打開一個文件(使用fopen()函數)
  • 讀學生的姓名(使用龜etc())
  • 店,在一個結構

我的問題的某些部分名稱是我需要讀取任意長度的字符串轉換成的名字,我不知道如何來存儲字符串而不浪費內存(或寫入未分配的內存Y)。

編輯

我的第一個想法就是分配1個字節(char)的內存塊,然後調用realloc的()如果需要更多的字節,但是這似乎並沒有非常有效的。或者,如果數組已滿,然後在最後將字符複製到新的確切大小的內存塊中,也許我可以將數組翻倍。

+3

你的編輯建議realloc加倍的大小對我來說似乎很好。你可以從一個可能足夠大的數組開始(因爲你知道它是一個學生的名字),並且大部分時間避免重新分配數據。 Supercalifragilisticsuuralralidoscious Antidisestablishmentarianism先生沒有去你的學校。 – 2010-11-22 21:19:31

+0

@保羅 - 你確信他沒有? – DMan 2010-11-22 23:58:24

回答

5

不要擔心浪費100或1000個字節,這對於所有名字來說可能足夠長。 我可能只是把你正在讀取的緩衝區放入堆棧。

擔心寫在緩衝區的末尾。即緩衝區溢出。防止這個計劃!

當您將名稱存儲到結構中時,您可以使用malloc緩衝區來存儲所需的確切長度的名稱(不要忘記爲空終止符添加一個額外的字節)。

但是,如果你真的必須存儲任何長度的名字,那麼你可以用realloc來完成。 即分配一個大小爲50字節的malloc的緩衝區。

然後當你需要更多的空間時,使用realloc來增加它的長度。增加長度爲50個字節的塊,並跟蹤一個int的大小,以便知道何時需要再次增長。在某些時候,你將不得不決定緩衝區將會變多長,因爲它不能無限增長。

2

您可以逐字符讀取字符串,直到找到結尾,然後回退到開頭,分配合適大小的緩衝區,然後重新讀入該緩衝區,但除非您處於小型嵌入式系統中,否則可能是愚蠢的。首先,fgetc,fread等函數無論如何都會在O/S中創建緩衝區。

您可以分配一個足夠大的臨時緩衝區,使用長度有限的讀取(爲了安全),然後分配一個精確大小的緩衝區以將其複製到。除非您認爲它可能會超出可用堆棧空間,否則您可能希望在堆棧上而不是通過malloc分配臨時緩衝區。

如果您正在爲一個小型系統編寫單線程代碼,您可以在啓動時或靜態分配一個臨時緩衝區,並將其用於多種用途 - 但要非常小心,您的用法不能重疊!考慮到大多數系統的實現複雜性,除非你真的研究事情是如何工作的,否則編寫內存優化的代碼完全可能需要更多的內存而不是簡單的方法。變量初始化可能是另一個令人驚訝的浪費。

2

我的建議是要分配足夠大小的緩衝區:

char name_buffer [ 80 ]; 

一般來說,大多數的名字(至少常見的英文名)將在尺寸小於80個字符。如果你覺得你可能需要更多的空間,通過一切手段分配更多。

保留一個計數器變量來知道你有多少個字符已經閱讀到您的緩衝區:與fgetc()

int chars_read = 0; /* most compilers will init to 0 for you, but always good to be explicit */ 

此時,讀取字符的字符,直到你要麼打文件標記的結束或閱讀80字符(79真的,因爲你需要空終止符的空間)。將你讀過的每個字符存入你的緩衝區,增加你的計數器變量。

while ((chars_read < 80) && (!feof(stdin))) { 
    name_buffer [ chars_read ] = fgetc (stdin); 
    chars_read++; 
} 
if (chars_read < 80) 
    name_buffer [ chars_read ] = '\0'; /* terminating null character */ 

我在這裏假設您正在閱讀從stdin。一個更完整的例子還將檢查錯誤,驗證從流中讀取的字符是否對某個人的姓名有效(例如,沒有數字)等。如果嘗試讀取的數據多於您分配空間的數據,則打印一個錯誤消息給控制檯。

我的理解是希望保持儘可能小的緩衝區,只分配需要的內容,但學習如何編程的一部分就是了解代碼/數據大小,效率和代碼可讀性的權衡。您可以使用mallocrealloc,但它使代碼比所需的複雜得多,它引入了可能會出現錯誤的位置 - NULL指針,數組索引超出範圍錯誤等等。對於大多數實際情況,分配什麼應該足夠爲您的數據要求加上少量的呼吸空間。如果你發現你遇到很多數據超過緩衝區大小的情況,調整你的緩衝區以適應它 - 這就是調試和測試用例的用處。

相關問題