簡體   English   中英

在不使用getc的情況下使用fscanf直到EOF

[英]Using fscanf until EOF without using getc

我有一個由2個字節的序列組成的文本文件,必須將其存儲在數組中。

我已經聲明了FILE *ptr

我如何不使用方法就循環到EOF:

while(c = getc() != EOF)
{
// do something 
}

我想按照(PSEUDOCODE)實現一些東西:

while (ptr is not pointing to the end of the file)
{
fscanf(...)  // I will read in the bytes etc.
}

getc()方法對我來說效果不佳,因為我一次讀取的是2個字節的塊。

您可以使用fread讀取多個字節。 fread返回它能夠讀取的項目數。

例如,要讀取2字節的塊,可以使用:

while ((fread(target, 2, 1, ptr) == 1) {
    /* ... */
}

這里2是每個“項目”中的字節數,而1是要在每次調用中讀取的“項目”數。

通常,您不應使用feof()控制何時終止輸入循環。 使用您正在使用的任何輸入例程返回的值。 不同的輸入功能在它們提供的信息方面有所不同。 您必須閱讀所用文檔的文檔。

請注意,這會將行尾視為單個'\\n'字符。 您說您正在從文本文件中讀取; 尚不清楚您要如何處理行尾。 如果文件的字符數為奇數,則還應該確定要執行的操作。

另一種選擇是在循環中兩次調用getc()兩次檢查其結果。

判斷何時到達文件末尾的唯一方法是嘗試讀取過去,但讀取失敗。 (是的,有一個feof()函數,但是僅您嘗試讀取文件末尾之后才返回true。)

這意味着,如果要使用fscanf()讀取輸入,則需要檢查的是fscanf()本身的返回值。

具體來說, fscanf()返回已成功讀取的項目數,如果輸入在可以讀取任何內容之前結束,則返回EOF (這是一個負值,通常為-1)。 因此,您的輸入循環可能看起來像這樣:

while (1) {
    /* ... */

    int n = fscanf(ptr, "...", ...);

    if (n == EOF && !ferror(ptr)) {
        /* we've reached the end of the input; stop the loop */
        break;
    } else if (n < items_requested) {
        if (ferror(ptr)) perror("Error reading input file");
        else fprintf(stderr, "Parse error or unexpected end of input!\n");
        exit(1);  /* or do whatever you want to handle the error */
    }

    /* ... */
}

也就是說,可能還有其他選擇。 例如,如果您的輸入被構造為行(很多文本輸入是行), 則最好通過fgets()逐行讀取輸入,然后使用sscanf()解析行。

此外,技術上, 偷看前面輸入一個字節的方式,使用ungetc() 也就是說,您可以執行以下操作:

int c;
while ((c = getc(ptr)) != EOF) {
    ungetc(c, ptr);
    /* ... now read and parse the input ... */
}

問題在於,這只會檢查您是否可以在EOF之前再讀取一個字節。 它沒有, 也不能 ,實際上檢查您的fscanf()調用是否具有足夠的數據來匹配所有請求的項。 因此,無論如何,您仍然仍然需要檢查fscanf()的返回值-如果要執行此操作,也可以將其用於EOF檢測。

暫無
暫無

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

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