代碼中`while(!feof(fp)) { printf("%s", fgets(buf, 100, fp)); }`導致最後多輸出`(null)`,原因是**`feof`在讀取失敗後才置位,循環多執行一次**且`fgets`返回`NULL`被`printf("%s")`打印為`(null)`。本文解析原理並給出標準讀取模式。
while (fgets(buf, sizeof(buf), fp) != NULL) {
printf("%s", buf); // buf已包含換行符
}
do {
if (fgets(buf, sizeof(buf), fp) == NULL) break;
printf("%s", buf);
} while (!feof(fp));
int line = 0;
while (fgets(buf, sizeof(buf), fp)) {
printf("%d: %s", ++line, buf);
}
// ❌ 錯誤
while (!feof(fp)) {
printf("%s", fgets(buf, 100, fp));
}
// ✅ 正確
while (fgets(buf, 100, fp)) {
printf("%s", buf);
}
原代碼混用`fputc`、`fputs`、`fwrite`、`fprintf`寫入,且多次手動寫入`\n\r`,導致文件換行符混亂(`\r\n` vs `\n`)。建議統一用`fprintf(fp, "%s\n", str)`或`fputs(str, fp); fputc('\n', fp);`,僅用`\n`,由運行庫處理平台差異。
鐵律:讀文件循環條件永遠用 `fgets/fread/fscanf` 等讀取函數的返回值判斷,絕不單獨用 `feof`。