CArchive 配合 CFile::typeText 進行**循序讀寫**,**不支援**原地修改某一行 (插入/刪除/取代) 的隨機存取。嘗試同時開啟一個 load 一個 store 的 CArchive 共用同一 CFile,會導致緩衝區、檔案指標互相衝突,造成資料損毀或寫入失敗。
BOOL ModifyStudentRecord(CString targetSno, const Student& newData) {
CFile file;
if (!file.Open(_T("D:\\SIMS.txt"), CFile::modeRead | CFile::typeText)) {
return FALSE;
}
// 1. 全部讀入 CStringArray
CStringArray lines;
CArchive arRead(&file, CArchive::load);
CString line;
while (arRead.ReadString(line)) {
lines.Add(line);
}
arRead.Close();
file.Close();
// 2. 在記憶體中修改
BOOL found = FALSE;
for (INT_PTR i = 0; i < lines.GetCount(); ++i) {
CString curLine = lines[i];
// 解析學號 (假設第一欄為學號,逗號分隔)
int commaPos = curLine.Find(',');
if (commaPos != -1) {
CString sno = curLine.Left(commaPos);
if (sno == targetSno) {
// 重建該行
CString newLine;
newLine.Format(_T("%s,%s,%s,%d,%d,%d,%d"),
newData.sno, newData.name, newData.major,
newData.comp, newData.math, newData.eng, newData.gym);
lines.SetAt(i, newLine);
found = TRUE;
break;
}
}
}
if (!found) return FALSE;
// 3. 整體寫回 (覆蓋原檔)
if (!file.Open(_T("D:\\SIMS.txt"), CFile::modeCreate | CFile::modeWrite | CFile::typeText)) {
return FALSE;
}
CArchive arWrite(&file, CArchive::store);
for (INT_PTR i = 0; i < lines.GetCount(); ++i) {
arWrite.WriteString(lines[i]);
arWrite.WriteString(_T("\r\n")); // 明確換行
}
arWrite.Close();
file.Close();
return TRUE;
}
MoveFileEx 替換)。採用**暫存檔法**:開啟原檔讀取 + 建立暫存檔寫入,逐行處理,最後 DeleteFile 原檔 + MoveFile 暫存檔→原檔。同樣不需雙向 CArchive 共用 CFile。