原代碼先讀所有學號存陣列,再 `fseek` 定位行首,但 `RECORDLENGTH` 固定 1000 導致定位偏移 (每行長度不一)。
#include
#include
struct Student {
long long Sno; char Sname[20], Ssex[6], Sdept[20]; int Sage;
};
int main() {
FILE* fp = fopen("StudentData.txt", "r");
if (!fp) { perror("open"); return 1; }
long long target; printf("請輸入學號: "); scanf("%lld", &target);
char line[1024];
Student s; bool found = false;
while (fgets(line, sizeof(line), fp)) {
if (sscanf(line, "%lld %19s %5s %d %19s", &s.Sno, s.Sname, s.Ssex, &s.Sage, s.Sdept) == 5) {
if (s.Sno == target) { found = true; break; }
}
}
fclose(fp);
if (found) {
printf("學號 姓名 性別 年齡 系所\n");
printf("%lld %s %s %d %s\n", s.Sno, s.Sname, s.Ssex, s.Sage, s.Sdept);
} else {
printf("查無學號 %lld\n", target);
}
return 0;
}
// 離線建立
unordered_map idx; // Sno -> file offset
FILE* fp = fopen("StudentData.txt", "r");
long long pos = 0; char line[1024];
while (true) {
long long cur = ftell(fp);
if (!fgets(line, sizeof(line), fp)) break;
long long sno; if (sscanf(line, "%lld", &sno)==1) idx[sno] = cur;
}
// 查詢時
auto it = idx.find(target);
if (it != idx.end()) {
fseek(fp, it->second, SEEK_SET);
fgets(line, sizeof(line), fp);
// 解析輸出
}
「邊讀邊比對」解決 99% 教學級查詢需求;大檔高頻查詢才需建立索引檔。