[英]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.