C語言中文件操作Error處理的方法示例
一. C 中的 ferror() 函數(shù)
在 C 語言中,ferror() 是一個內置函數(shù),用于在文件操作期間檢查文件是否發(fā)生錯誤。它提供了一種簡單的方法,在你的 C 程序中進行文件操作時不會中斷。
1.ferror 語法
ferror() 是一個標準庫函數(shù),定義在頭文件 <stdio.h> 中。
ferror(fptr) **參數(shù):** 接收一個文件流指針作為參數(shù)。 **返回值:** - 如果文件有錯誤,返回一個非零值。 - 否則,返回 0。 **注意:** 要使用 `ferror()` 檢查文件錯誤,文件必須先打開。
2.ferror() 的示例
示例 1:寫入數(shù)據(jù)時檢查錯誤
#include <stdio.h>
int main() {
FILE *fptr = fopen("gfg.txt", "w");
// 向文件寫入數(shù)據(jù)
fprintf(fptr, "Hello, GFG!");
// 寫入后檢查是否有錯誤
if (ferror(fptr) == 0)
printf("數(shù)據(jù)寫入成功。");
fclose(fptr);
return 0;
}
輸出:
數(shù)據(jù)寫入成功。
示例 2:讀取數(shù)據(jù)時檢查錯誤
#include <stdio.h>
int main() {
FILE *fptr = fopen("gfg.txt", "w+");
fprintf(fptr, "GeeksForGeeks!");
rewind(fptr);
char d[14];
while (fscanf(fptr, "%s", d) != EOF)
// 讀取后檢查是否有錯誤
if (ferror(fptr) == 0) {
for (int i = 0; i < sizeof(d); i++) {
printf("%c", d[i]);
}
printf("\n沒有錯誤,數(shù)據(jù)讀取成功");
}
fclose(fptr);
return 0;
}
輸出:
GeeksForGeeks! 沒有錯誤,數(shù)據(jù)讀取成功
二. C 中的 EOF、getc() 和 feof()
1.什么是 EOF?
在 C 中,EOF 是一個常量宏,定義在頭文件 <stdio.h> 中,用于表示文件結束。它被多個文件讀取函數(shù)使用,比如 fread()、gets()、getc() 等。 EOF 的值是由實現(xiàn)定義的,但通常是 -1。
2.getc() 函數(shù)
getc() 函數(shù)用于從給定的文件流中讀取一個字符。它是以宏的形式在 <stdio.h> 中實現(xiàn)的。
語法:
getc(fptr); #### 參數(shù): - `fptr`:指向要讀取數(shù)據(jù)的文件流的指針。 #### 返回值: - 返回從文件流中讀取的字符。 - 如果發(fā)生錯誤或到達文件末尾,返回 `EOF`。
3.feof() 函數(shù)
feof() 函數(shù)用于檢查文件指針是否指向文件末尾。如果到達文件末尾,它返回一個非零值;否則返回 0。
語法:
feof(fptr); #### 參數(shù): - `fptr`:指向要讀取數(shù)據(jù)的文件流的指針。 #### 返回值: - 如果到達文件末尾,返回非零值(通常是 1)。 - 否則返回 0。
4.為什么需要 feof()?
getc() 在到達文件末尾時會返回 EOF,但它在讀取失敗時也會返回 EOF。因此,僅靠比較 getc() 的返回值和 EOF 并不足以判斷是否真的到了文件末尾。為了解決這個問題,C 提供了 feof() 函數(shù)。
示例 1:無法區(qū)分錯誤還是文件結束
#include <stdio.h>
int main() {
FILE *fptr = fopen("file.txt", "w");
char ch;
// 嘗試用 getc() 讀取一個字符
ch = getc(fptr);
// 處理 EOF 返回值
if (ch == EOF)
printf("文件結束或無法讀取");
else
printf("讀取的字符:%c", ch);
fclose(fptr);
return 0;
}
輸出:
文件結束或無法讀取
在上述程序中,文件是以“只寫”模式打開的,getc() 無法讀取數(shù)據(jù),但它仍然返回 EOF,這使得我們難以判斷錯誤的來源。此時可以使用 feof() 來明確判斷是否到達文件末尾。
示例 2:使用 feof() 明確判斷文件結束
#include <stdio.h>
int main() {
FILE *fptr = fopen("file.txt", "w");
char ch;
// 嘗試用 getc() 讀取一個字符
ch = getc(fptr);
// 處理 EOF 返回值
if (ch == EOF) {
// 檢查是文件結束,還是讀取失敗
if (feof(fptr))
printf("文件結束");
else
printf("無法讀取");
} else
printf("讀取的字符:%c", ch);
fclose(fptr);
return 0;
}
輸出:
無法讀取
三. C 中的 clearerr() 函數(shù)
在 C 語言中,文件操作中的錯誤可以通過 ferror() 和 feof() 函數(shù)來檢測。但這些錯誤標志一旦設置就會一直保留,直到被顯式清除。clearerr() 是一個標準庫函數(shù),用于在你進行文件讀寫操作時手動清除這些錯誤標志。
語法 : clearerr() 是定義在頭文件 <stdio.h> 中的標準庫函數(shù)。
clearerr(fptr); #### 參數(shù): - `fptr`:指向文件流的文件指針。 #### 返回值: - 該函數(shù)**沒有返回值**(`void`)。
示例 1:
#include <stdio.h>
int main() {
FILE *fptr = fopen("gfg.text", "rw+");
// 清除錯誤和 EOF 標志
clearerr(fptr);
if (!feof(fptr))
printf("EOF 重置成功");
return 0;
}
輸出:
EOF 重置成功
示例 2:清除 EOF 標志的實際用法
#include <stdio.h>
int main() {
FILE *fptr = fopen("gfg.txt", "w+");
fprintf(fptr, "GeeksForGeeks!");
// 不斷讀取直到遇到 EOF
while (fgetc(fptr) != EOF);
if (feof(fptr)) {
printf("遇到 EOF\n");
}
// 使用 clearerr() 清除 EOF 標志
clearerr(fptr);
if (!feof(fptr)) {
printf("EOF 已成功重置");
}
fclose(fptr);
return 0;
}
輸出:
遇到 EOF EOF 已成功重置
總結:
clearerr()用于清除文件流的錯誤標志和 EOF 標志。- 它不會返回任何值,只是重置狀態(tài)。
- 常用于重復讀寫文件或調試文件操作時。
四. C 語言文件操作中的錯誤處理
文件操作是 C 編程中的常見任務,但可能遇到各種錯誤,需要優(yōu)雅地處理。良好的錯誤處理能讓程序在面對“文件缺失”“權限不足”等突發(fā)情況時不至于崩潰。本文將學習如何在 C 語言文件操作中處理這些常見錯誤。
常見文件操作錯誤一覽
| 錯誤 | 原因 |
|---|---|
| 文件未找到 | 試圖打開一個不存在的文件 |
| 權限被拒絕 | 對文件訪問權限不足 |
| 磁盤已滿 | 寫入時磁盤空間耗盡 |
| 文件已存在 | 用 “w” 模式創(chuàng)建已存在的文件 |
| 無效文件指針 | 使用 NULL 或非法 FILE* 進行讀寫 |
| 已到文件尾 (EOF) | 讀操作越過文件末尾 |
| 文件未打開 | 在未成功打開的文件上繼續(xù)操作 |
若不做錯誤檢查,程序可能出現(xiàn)異常行為:提前終止或輸出錯誤結果。
錯誤處理技巧(不一定非要這么處理,只是簡單建議,要靈活處理)
1. 處理 “文件未找到”
以只讀 “r” 或追加 “a” 模式打開文件時,若文件不存在,fopen 返回 NULL。用 perror 打印系統(tǒng)提示。
#include <stdio.h>
int main(void) {
FILE *file = fopen("file.txt", "r");
if (file == NULL) {
perror("Error");
return 1;
}
fclose(file);
return 0;
}
輸出:
Error: No such file or directory
2. 處理 “權限被拒絕”
文件存在但無權限時,fopen 同樣返回 NULL,perror 會輸出 “Permission denied”。
FILE *file = fopen("/restricted/file.txt", "w");
if (file == NULL) {
perror("Permission denied");
}
3. 處理 “磁盤已滿”
寫入后通過 ferror 檢測流錯誤。
#include <stdio.h>
int main(void) {
FILE *fptr = fopen("file.txt", "w");
if (fptr == NULL) {
perror("Error opening file");
return 1;
}
fprintf(fptr, "Writing to file");
if (ferror(fptr)) {
perror("Error writing to file");
}
fclose(fptr);
return 0;
}
輸出示例:
Error writing to file: Permission denied
4. 處理 “文件已存在”
用 “wx” 模式創(chuàng)建新文件;若文件已存在,fopen 返回 NULL 并置 errno 為 EEXIST。
#include <stdio.h>
#include <errno.h>
int main(void) {
FILE *fptr = fopen("test.text", "wx");
if (fptr == NULL) {
if (errno == EEXIST)
printf("File already exist\n");
return 1;
}
fprintf(fptr, "This is a new file.");
fclose(fptr);
return 0;
}
輸出:
File already exist
5. 處理 “無效文件指針”
任何讀寫前都先判斷指針是否為 NULL。
FILE *file = NULL;
if (file == NULL) {
printf("Invalid file pointer. File operations cannot proceed.\n");
}
6. 處理 “已到文件尾 (EOF)”
讀取時用 feof 區(qū)分“正常讀完”與“讀取出錯”。
#include <stdio.h>
int main(void) {
FILE *file = fopen("test.txt", "r");
int ch;
while ((ch = fgetc(file)) != EOF)
putchar(ch);
if (feof(file))
printf("End of file reached.");
else if (ferror(file))
printf("Error reading the file.");
fclose(file);
return 0;
}
輸出:
End of file reached.
7. 處理 “文件未打開”
fopen 返回 NULL 即表示打開失敗,直接判斷即可。
#include <stdio.h>
int main(void) {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
printf("File could not be opened.\n");
} else {
printf("File opened successfully.\n");
fclose(file);
}
return 0;
}
輸出:
File could not be opened.
8. 處理 “關閉文件失敗”
fclose 返回 -1 表示關閉出錯。
#include <stdio.h>
int main(void) {
FILE *fptr = fopen("test.txt", "w");
fprintf(fptr, "Writing to file");
if (fclose(fptr) == -1)
printf("File closing error");
else
printf("File closed");
return 0;
}
輸出:
File closing error
以上就是C語言中文件操作Error處理的方法示例的詳細內容,更多關于C語言文件操作Error處理的資料請關注腳本之家其它相關文章!
相關文章
C語言+shell實現(xiàn)linux網(wǎng)卡狀態(tài)檢測
這篇文章主要為大家詳細介紹了C語言+shell實現(xiàn)linux網(wǎng)卡狀態(tài)檢測,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06
詳解C語言中getgid()函數(shù)和getegid()函數(shù)的區(qū)別
這篇文章主要介紹了詳解C語言中getgid()函數(shù)和getegid()函數(shù)的區(qū)別,注意getegid只返回有效的組識別碼,需要的朋友可以參考下2015-08-08
linux c程序中獲取shell腳本輸出的實現(xiàn)方法
以下是對在linux下c程序中獲取shell腳本輸出的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友可以過來參考下2013-08-08
C++學習貝葉斯分類器實現(xiàn)手寫數(shù)字識別示例解析
這篇文章主要介紹了在C++學習中如何采用貝葉斯分類器來實現(xiàn)手寫數(shù)字識別的示例及解析有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10

