HOWTO · MATLAB

MATLAB fprintf 表格

可以使用 MATLAB 中的 fprintf()函数来打印格式化的文本和变量。

本页内容

使用 MATLAB fprintf,搭配格式说明和相匹配的值,即可打印易读的表格。使用字段宽度转换时,在各字段之间加入普通空格,并在每行末尾添加换行转义序列(\n)。制表符(\t)也可用于分隔字段,但制表位不一定能让各列始终对齐。同一次调用既可以将内容写入命令窗口,也可以写入文件。

理解 fprintf 格式说明符

基本形式为 fprintf(formatSpec, values...)。格式说明由字符向量或字符串组成,其中可以包含普通文本和转换说明符。每个转换说明符都会使用一个传入值:%s 用于格式化文本,%d 用于格式化整数,%f 用于格式化定点数。例如,fprintf('Count: %d\n', 3) 会写出标签、数值和换行符。

转换说明符可以包含标志、最小字段宽度和精度,例如 %-10s 或 %8.2f。减号标志会使值左对齐;不加该标志时,值会右对齐。%8.2f 中的精度表示小数点后显示两位。字段宽度只是最小宽度,因此值较长时会超出该宽度,而不会被截断。若要在输出中显示百分号,应写作 %%。

如果传入的值包含矩阵,fprintf 会按 MATLAB 列优先顺序处理矩阵元素,并按需重复使用格式。它不会自动判断每个格式转换对应矩阵中的一列。要生成按行排列的表格,应像下面的示例那样明确索引每行的值。完整语法和转换选项请参阅 MathWorks fprintf 参考文档。

根据 MATLAB 数据构建表格

表头和数据应保持相同的顺序。此示例在字段之间使用普通空格分隔,并在每行末尾添加 \n;字段宽度转换会预留空间,让各值对齐。也可以用 \t 转义序列分隔字段,但文本长度或显示设置不同,制表位就无法保证列始终对齐。循环每次传入一行的值。示例使用常规 MATLAB 语法,配置的 Octave 运行环境也接受这种语法。

运行此示例:

本节中的代码以及显示的标签或输出仍为英文。

names = {'Ava', 'Milo', 'Zoe'};
scores = [85, 92, 78];
means = [91.25, 84.50, 96.75];

fprintf('%-8s %6s %8s\n', 'Name', 'Score', 'Mean');
for k = 1:numel(names)
    fprintf('%-8s %6d %8.2f\n', names{k}, scores(k), means(k));
end
Name      Score     Mean
Ava          85    91.25
Milo         92    84.50
Zoe          78    96.75

表头和数据行的格式各包含三个转换说明符,顺序与传入值一致:名称、分数,然后是平均值。换行符会结束当前输出行。如果直接传入矩阵,请记住,MATLAB 会先从上到下遍历第一列,再处理下一列;应调整数据布局或使用索引,使其符合表格所需的顺序。

对齐列并格式化数值

应根据最长的预期标题或数值选择字段宽度。在示例中,%-8s 为每个名称至少预留八个字符,并使其左对齐。%6d 为整数分数预留六个字符,而 %8.2f 预留八个字符,并为平均值显示两位小数。如果内容超过指定宽度,字段会自动扩展;因此,设计固定宽度的报告时,应检查有代表性的数值。

制表符(\t)会移至下一个制表位,而不是在每个值后移至固定的字符位置。文本长度不一,或输出环境的制表位设置不同时,列看起来可能无法对齐。若要获得可预测的列布局,可使用 %-12s %8.2f 这样的宽度转换,并选择使用等宽字体的文本编辑器或控制台。精度会改变显示时的舍入结果,但不会改变存储的值。

将格式化的表格输出写入文件

将文件标识符作为 fprintf 的第一个参数传入,即可将相同的格式化文本写入文件。使用 fopen 打开文件,检查是否成功打开,并在写入完成后关闭文件。此独立示例会将一个小表格写入临时路径,并使用 onCleanup,确保即使后续代码提前退出,也会关闭文件标识符。

本节中的代码以及显示的标签或输出仍为英文。

names = {'Ava', 'Milo'};
scores = [85, 92];
path = [tempname(), '.txt'];
fileID = fopen(path, 'w');
if fileID >= 0
    closeFile = onCleanup(@() fclose(fileID));
    fprintf(fileID, '%-8s %6s\n', 'Name', 'Score');
    for k = 1:numel(names)
        fprintf(fileID, '%-8s %6d\n', names{k}, scores(k));
    end
    clear closeFile
end

'w' 模式会创建或替换目标文件,因此应选择可以安全覆盖的路径。如果 fopen 返回负标识符,表示文件未能打开;写入前请检查路径和权限。若要生成多份报告,应谨慎构造输出路径,并在写入完成后关闭每个文件标识符,以释放文件资源。

排查常见的表格格式问题

如果列中显示了错误的值,请比较转换说明符的顺序与传给 fprintf 的值的顺序。每个 %s、%d 或 %f 都必须接收兼容的值;类型不匹配可能导致输出误导读者,或产生格式警告。对于矩阵,列优先遍历通常可以解释数值为何按意料之外的顺序出现。应使用标量行索引,或有意转置、重新排列数据,不要假设 fprintf 会把转换说明符映射到各列。

如果列没有对齐,可使用明确的字段宽度代替制表符,并为最长的文本和数值留出空间。如果小数显示时发生舍入,可调整 %.4f 等转换说明符中的精度;这只会影响文本表示。如果文件为空或内容不完整,请确认 fopen 已成功打开文件、每次写入都指定了文件标识符,并在最后一行写入后关闭文件。保持格式转换、传入值和分隔符的顺序一致,表格会更容易检查和维护。