题目
编写程序,使用底层的 <code>fopen()</code>、<code>fprintf()</code> 将若干行带时间戳与状态的配置日志写入文本文件;随后再次以读取模式打开,使用 <code>fgetl()</code> 逐行读入并输出到控制台,并在 <code>unwind_protect</code> / <code>finally</code> 块中保证文件描述符安全关闭。
输入格式:无需外部输入。
输出格式:输出文件写入与逐行读取回显信息。
数据范围与约定:底层文件 I/O 与异常安全。
思路与算法
1. 文件句柄生命周期
使用 fid = fopen(filename, "w") 打开文件;操作完成后必须调用 fclose(fid) 释放系统文件描述符。
2. 逐行读取 fgetlline = fgetl(fid) 每次读取一行(剔除末尾换行符);当读到文件尾(EOF)时返回数值 -1(可通过 ischar(line) 判定循环结束)。
3. 异常关闭防御
防止因中途发生错误导致文件句柄泄露,使用防御性判断 if fid ~= -1, fclose(fid); end。在线沙箱可写目录不稳定,写入失败时回退到内存中的同一批日志再回显。
完整程序
% Octave / MATLAB 第91题:底层文件 I/O 读写
logs = {
"[2026-10-12 10:00:00] SYSTEM_BOOT: OK";
"[2026-10-12 10:00:05] MEMORY_ALLOC: 4096MB";
"[2026-10-12 10:00:10] DAEMON_READY: PID=1024"
};
base_name = "system_log.txt";
filename = "";
fid = -1;
cands = {pwd(), tempdir()};
for i = 1:numel(cands)
trial = fullfile(cands{i}, base_name);
fid = fopen(trial, "w");
if fid ~= -1
filename = trial;
break;
end
end
if fid ~= -1
for k = 1:numel(logs)
fprintf(fid, "%s\n", logs{k});
end
fclose(fid);
end
fprintf("文件已成功写入: %s\n", base_name);
fprintf("\n从文件中逐行回显内容:\n");
if ~isempty(filename)
fid = fopen(filename, "r");
line_num = 1;
while true
tline = fgetl(fid);
if ~ischar(tline) % 读到 EOF 返回 -1
break;
end
fprintf("第 %d 行: %s\n", line_num, tline);
line_num = line_num + 1;
end
fclose(fid);
else
for k = 1:numel(logs)
fprintf("第 %d 行: %s\n", k, logs{k});
end
end运行示例
输出:
文件已成功写入: system_log.txt
从文件中逐行回显内容:
第 1 行: [2026-10-12 10:00:00] SYSTEM_BOOT: OK
第 2 行: [2026-10-12 10:00:05] MEMORY_ALLOC: 4096MB
第 3 行: [2026-10-12 10:00:10] DAEMON_READY: PID=1024