fopen 是 C 標準庫函式,fopen_s 為 C11 附錄 K / Microsoft 延伸的安全版本。兩者在參數順序、回傳值、錯誤處理上有關鍵差異,混用易導致 Bug。
| 項目 | fopen | fopen_s |
|---|---|---|
| 原型 | FILE* fopen(const char* filename, const char* mode); | errno_t fopen_s(FILE** pFile, const char* filename, const char* mode); |
| 檔案指標 | 回傳值 | 透過第一參數 pFile 輸出 |
| 成功回傳 | 非 NULL 指標 | 0 |
| 失敗回傳 | NULL | 非零錯誤碼(如 EINVAL、ENOENT) |
| 參數檢查 | 無 | 檢查空指標、模式字串合法性 |
FILE* fp = fopen("data.txt", "w");
if (!fp) {
perror("fopen failed");
return -1;
}
// ... 使用 fp
fclose(fp);
FILE* fp = nullptr;
errno_t err = fopen_s(&fp, "data.txt", "w");
if (err != 0 || !fp) {
std::cerr << "fopen_s failed, errno=" << err << '\n';
return -1;
}
// ... 使用 fp
fclose(fp);
fopen_s 多一層間接,第一參數為 FILE**fopen 回傳指標,fopen_s 回傳錯誤碼fopen_s 會驗證參數合法性,減少未定義行為fopen 為標準 C,跨平台通用;fopen_s 主要支援 Windows/MSVC、部分 C11 實作fopen 搭配手動參數檢查fopen_s,並檢查 errno_tstd::filesystem + std::fstream 完全避開 C API