簡體   English   中英

由於使用 fgets() 將文件中的行讀入結構數組而導致分段錯誤

[英]Segmentation fault as a result of using fgets() to read lines from a file into a struct array

我目前正在學習 C,需要一些代碼幫助。

假設有一個名為“books.txt”的文件,它在文件的新行中包含了幾本書的名稱。 我試圖獲取每本書的名稱以用於我程序的其余部分。

為此,我創建了以下內容:

struct bookData { // This is my struct to encapsulate book information
     char name[50]; // Name of book
     // Other struct variable
     // Other struct variable
};

現在我需要獲取每本書的名稱並將它們放入一個結構數組中。 下面是我如何去做。

struct bookData booksList[numBooks]; // numBooks is the number of books in "books.txt"

int i;
for(i = 0; i < numBooks; i++) {
     fgets(booksList[i].name, 50, books);
     // Books is the "books.txt" file that was opened for reading
}

當我運行此代碼時,我遇到了分段錯誤。 我相信問題在於 for 循環的使用。 但是我不確定如何糾正這個問題,甚至不確定為什么循環會導致出現分段錯誤。 當我簡單地放置線時,

fgets(booksList[0].name, 50, books);

沒有 for 循環,不會發生錯誤,代碼運行並打印書名就好了。

我試圖了解為什么我的代碼中出現錯誤。 如果有人可以就如何修復錯誤給我建議,我將不勝感激。 預先感謝您花時間閱讀/回答我的問題!

編輯:numBooks 本質上是“books.txt”文件中的行數。 這轉化為這個特定問題的書籍數量。 numBooks 是用以下代碼計算的:

char c; 
int numBooks; 
while((c = fgetc(books)) != EOF) { 
    if(c == '\n') { 
         numBooks++; 
    } 
}

編輯#2:謝謝大家的幫助!!!

以下代碼是錯誤的,可以合理地預期會導致問題:

char c; 
int numBooks; 
while((c = fgetc(books)) != EOF) { 
    if(c == '\n') { 
         numBooks++; 
    } 
}

首先, numBooks未初始化,以后使用它可能會調用未定義的行為。

其次,雖然在大多數系統上引起問題的可能性要小得多,但fgetc返回int ,它通常具有更寬的域(可以表示比unsigned char更多的值)。 這樣做是有原因的。 fgetc返回的任何實際字符值都將作為unsigned char (即僅正數)值。 失敗將導致EOF僅限負數)。 這意味着fgetc通常可以返回 257 個值之一,並且通過直接轉換為char您將丟棄這些值之一:錯誤處理值。 換句話說,您無法再判斷fgetc成功。 當你到達EOF時會發生什么? 您將其轉換為char ,將其視為字符值(如果不是),然后再試一次..? 錯誤的答案!

總之, fgetc返回int ,因此將返回值存儲在int ...


numBooks達到INT_MAXnumBooks++;時會出現另一個問題numBooks++; 會導致溢出。 從技術上講,這是未定義的行為,理論上可能會導致分段錯誤……但我從未親自見過。 盡管如此,您可能應該使用unsigned類型,因為文件中的條目數為負數是沒有意義的,是嗎?

細想一下,如果numBooksstruct bookData booksList[numBooks]; 為負數(或足夠大的數字),當您訪問更高的元素時,您可能會開始看到分段違規。

總結:當您只希望看到正數時使用無符號類型,並為大數組使用動態分配(例如malloc )。


請注意,這並未涵蓋所有可能性,因為您尚未提供MCVE,因此這樣做是不可能/不切實際的; 您的段錯誤很可能是由您未提供的其他代碼引起的。 如果您更新此問題,請告訴我,以便我可以更新此答案並讓世界保持旋轉:)

暫無
暫無

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

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