题目

编写程序,使用底层的 <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. 逐行读取 fgetl
line = 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