程式碼看似正確,執行卻找不到檔案或內容異常,通常是路徑、權限、編碼三大問題。
#include <stdio.h>
#define n 2
struct student { int number; char name[10]; int score; } stu[n];
void save() {
FILE *fp;
if ((fp = fopen("file1.dat", "w")) == NULL) { // 問題 1:相對路徑
printf("error"); return;
}
for (int i = 0; i < n; i++)
if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)
printf("error");
fclose(fp);
}
// 問題:fopen("file1.dat", "w") 相對於「目前工作目錄」
// Visual Studio 預設工作目錄 = 專案目錄 (含 .sln 檔處)
// 執行檔目錄 = x64/Debug/ 或 Debug/
// 解決方案 1:使用絕對路徑
FILE *fp = fopen("C:\\Data\\file1.dat", "wb"); // 注意雙反斜線或正斜線
// 解決方案 2:取得執行檔目錄動態組合
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);
PathAppend(path, "file1.dat");
FILE *fp = fopen(path, "wb");
// 錯誤:Windows 下 "w" 為文字模式,會將 \n 轉換為 \r\n
// 正確:二進位檔案必須用 "wb" / "rb"
FILE *fp = fopen("file1.dat", "wb"); // 寫入二進位
FILE *fp = fopen("file1.dat", "rb"); // 讀取二進位
// Program Files、System32、根目錄 需要管理員權限
// 解決方案:
// 1. 寫入使用者目錄:%USERPROFILE%\Documents\MyApp\
// 2. 使用 SHGetKnownFolderPath 取得正確路徑
// 3. 資訊清單要求管理員權限 (不建議常駐程式)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h> // Windows API for path
#include <shlobj.h> // SHGetKnownFolderPath
#define N 2
typedef struct {
int number;
char name[10];
int score;
} Student;
Student stu[N];
void getAppDataPath(char *buffer, size_t size) {
PWSTR documentsPath;
SHGetKnownFolderPath(&FOLDERID_Documents, 0, NULL, &documentsPath);
char narrowPath[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, documentsPath, -1, narrowPath, MAX_PATH, NULL, NULL);
CoTaskMemFree(documentsPath);
snprintf(buffer, size, "%s\\MyApp\\students.dat", narrowPath);
}
int main() {
char filePath[MAX_PATH];
getAppDataPath(filePath, sizeof(filePath));
// 建立目錄
char dirPath[MAX_PATH];
strcpy(dirPath, filePath);
PathRemoveFileSpec(dirPath);
CreateDirectory(dirPath, NULL);
// 輸入資料
for (int i = 0; i < N; i++) {
printf("Enter student %d (number name score): ", i+1);
scanf("%d %9s %d", &stu[i].number, stu[i].name, &stu[i].score);
}
// 寫入二進位檔案
FILE *fp = fopen(filePath, "wb");
if (!fp) { perror("fopen"); return 1; }
for (int i = 0; i < N; i++) {
if (fwrite(&stu[i], sizeof(Student), 1, fp) != 1) {
perror("fwrite");
fclose(fp);
return 1;
}
}
fclose(fp);
printf("Saved to: %s\n", filePath);
// 驗證讀取
fp = fopen(filePath, "rb");
Student readStu;
while (fread(&readStu, sizeof(Student), 1, fp) == 1) {
printf("Read: %d, %s, %d\n", readStu.number, readStu.name, readStu.score);
}
fclose(fp);
return 0;
}
"wb"/"rb" 二進位模式fopen、fwrite、fread 回傳值#pragma pack(1) 若需跨平台相容二進位檔案操作看似簡單,細節決定成敗。養成完整錯誤檢查與路徑管理習慣。