簡體   English   中英

文件讀取程序在while循環結束時掛起(linux c)

[英]File reading program hangs at end of while loop (linux c)

對不起這個小問題。 我正在逐字符讀取文件。 它似乎可以工作到最終運行(EOF),由於某種原因該程序會掛起。

雖然打印了while循環的最后一行“完成外部循環,in為0”,但是由於某種原因,即使條件為“(in!='0')”,循環也不會退出。 “完成的解析事件”行不會打印,程序會停止並且沒有響應。

char in = '1';
FILE *fid = fopen(filename, "r");
while (in != '0') {
    printf("Start of loop, in is %c\r\n", in);
    if ((in = fgetc(fid)) == EOF) 
        in = '0';

    /* Large block that does stuff depending on the value of in*/

    printf("Done outer loop, in is %c\r\n", in);

}

fclose(fid);
printf("Finished parsing events");
//fflush(stdout);

嘗試更改:

char in = '1';

至:

int in = '1';

首先, fgetc函數的返回類型是int 當您到達文件末尾時,將返回EOF (可能為-1 ,我認為它等於-1 )。 然后,將-1存儲在類型為charin變量中。 在standard中沒有定義它是否為char簽名,在您的情況下,它似乎是未簽名的,因此in變為255 然后將in提升為int類型以與EOF進行比較,但當然255 != -1 ,因此您處於無限循環中。

即使使用您發布的代碼,以及收到的有關使用fgetc(3)的答案,發布的代碼也不應掛起。 讓我們看看發生了什么:

fgetc(3)返回int -1值(作為int ,通常這樣定義常量EOF )來區分8位char的256種可能性,以及EOF條件(不是即將出現的數據值)從流中),然后將其轉換為char (使EOF只是一些有效輸入的別名)。 在這種情況下,您已將該條件同化為char類型的值之一,這是錯誤的。

但這通常不會使程序掛起(它甚至沒有定義未定義的行為,除了我們實際上不知道哪個char值將用作EOF條件的別名這一事實)。 程序將具有兩個條件來break循環 (如您所掩蓋的一樣)。 第一個是實際的EOF條件,第二個實際上是從輸入流接收輸入時將EOF轉換為的char

正如有人在評論中指出的那樣。 問題必須在較大的注釋塊中 ,您實際上已隱藏了。 即使您在執行之后執行了printf(3) ,而該塊的外部卻沒有執行,您也可能在隱藏塊中有錯誤,該錯誤僅在離開時才會顯示,並使該錯誤明顯在循環測試中您在代碼塊的開始處制作。

更改char in = '1'; int in = '1'; 是消除突然break s的好選擇,但是您的懸掛問題並不存在...您必須發布隱藏的塊才能獲得更多反饋。

重要的提示

嘗試習慣於編寫完整的失敗示例...不要編輯代碼以僅將其發布,而無需測試它是否繼續失敗(因為您沒有這樣做,我在下面演示了這一點),因此您不會得到這種答案(似乎比嘗試幫助您更火)。 至少必須對發布的代碼進行編輯以使其可運行 ,因為您僅粘貼了一段甚至無法編譯的代碼。 此類示例應該類似於我在下面發布的示例,但由於它不會失敗,因此無法用於解決您的問題。 對?

#include <stdio.h>             /* line added to make runnable */
#define filename "test.txt"    /* line added to make runnable */
int main()                     /* line added to make runnable */
{                              /* line added to make runnable */
    char in = '1';
    FILE *fid = fopen(filename, "r");
    while (in != '0') {
        printf("Start of loop, in is %c\r\n", in);
        if ((in = fgetc(fid)) == EOF) 
            in = '0';

        /* Large block that does stuff depending on the value of in*/

        printf("Done outer loop, in is %c\r\n", in);

    }

    fclose(fid);
    printf("Finished parsing events");
    //fflush(stdout);
}                              /* line added to make runnable */

它的運行如下所示(沒有任何掛起)(請注意, sed(1)命令用於添加將輸出作為輸出文本嵌入此處所需的四個空格,您不得在家中將其用於測試目的):

$ pru8 | sed -e 's/^/    /'
Start of loop, in is 1
Done outer loop, in is p
Start of loop, in is p
Done outer loop, in is s
Start of loop, in is s
Done outer loop, in is d

[...] <--- a lot more of repeating lines like the ones posted above.

Start of loop, in is  
Done outer loop, in is 

Start of loop, in is 

Done outer loop, in is 0
Finished parsing events
$ _

而且沒有掛。

暫無
暫無

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

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