文章目录
-
- 一、核心函数基础认知
- 二、fopen():打开文件的"第一步"
-
- [1. 基本语法](#1. 基本语法)
- [2. 实战示例:判断文件是否打开成功](#2. 实战示例:判断文件是否打开成功)
- 三、fscanf():读取文本文件内容
-
- [1. 基本语法](#1. 基本语法)
- [2. 场景1:读取纯数值文本文件](#2. 场景1:读取纯数值文本文件)
- [3. 场景2:读取混合格式文本文件](#3. 场景2:读取混合格式文本文件)
- [4. 场景3:读取纯文本字符串(如日志文件)](#4. 场景3:读取纯文本字符串(如日志文件))
- 四、fprintf():写入内容到文本文件
-
- [1. 基本语法](#1. 基本语法)
- [2. 场景1:写入数值矩阵到文本文件](#2. 场景1:写入数值矩阵到文本文件)
- [3. 场景2:追加内容到文本文件](#3. 场景2:追加内容到文本文件)
- [4. 场景3:写入混合格式内容(字符串+数值)](#4. 场景3:写入混合格式内容(字符串+数值))
- 五、fclose():关闭文件的"最后一步"
-
- [1. 基本语法](#1. 基本语法)
- [2. 关键注意事项](#2. 关键注意事项)
- 六、避坑指南:新手常见错误与解决方案
-
- [1. 坑1:文件路径错误导致fopen失败](#1. 坑1:文件路径错误导致fopen失败)
- [2. 坑2:fscanf读取矩阵时行列颠倒](#2. 坑2:fscanf读取矩阵时行列颠倒)
- [3. 坑3:写入文件后内容为空](#3. 坑3:写入文件后内容为空)
- [4. 坑4:覆盖原有文件导致数据丢失](#4. 坑4:覆盖原有文件导致数据丢失)
- 七、实战综合案例:批量处理文本数据
文本文件读写是MATLAB数据处理的基础技能,不管是读取实验数据、导出计算结果,还是批量处理文本格式的日志文件,都离不开 fopen()、 fscanf()、 fprintf()、 fclose()这四个核心函数。本文从实际应用场景出发,详解每个函数的用法、参数含义和实战案例,新手也能快速掌握从"读文件"到"写文件"的完整流程。
一、核心函数基础认知
先理清四个核心函数的定位,避免混淆用法:
| 函数名 | 核心作用 | 关键特点 |
|---|---|---|
fopen() |
打开文本文件 | 返回文件句柄(唯一标识),需判断是否打开成功 |
fscanf() |
读取文本文件内容 | 按指定格式读取,支持批量读取、按行读取 |
fprintf() |
写入内容到文本文件 | 支持格式化输出,可自定义文本格式(如数值、字符串) |
fclose() |
关闭打开的文件 | 必须执行,避免文件占用、数据丢失 |
前置知识点:文件打开模式
fopen()的第二个参数决定文件打开方式,新手必记常用模式:
'r':只读(默认),文件不存在则报错'w':写入(覆盖原有内容),文件不存在则创建'a':追加(在文件末尾写入),文件不存在则创建'r+':读写,文件不存在则报错'w+':读写(覆盖原有内容),文件不存在则创建
二、fopen():打开文件的"第一步"
1. 基本语法
matlab
fid = fopen(filename, mode); % 核心用法
[fid, message] = fopen(filename, mode); % 带错误信息返回(推荐)
fid:文件句柄(整数),成功打开时返回≥3的整数;失败时返回-1filename:文件路径(字符串),如'data.txt'(当前目录)、'D:\test\log.txt'(绝对路径)message:错误信息(文件打开失败时返回具体原因,如文件不存在、权限不足)
2. 实战示例:判断文件是否打开成功
matlab
% 打开当前目录下的data.txt,只读模式
[fid, msg] = fopen('data.txt', 'r');
if fid == -1 % 打开失败
disp(['文件打开失败:', msg]); % 输出错误原因
else % 打开成功
disp(['文件打开成功,句柄:', num2str(fid)]);
end
关键提醒 :打开文件后必须先判断fid是否为-1,避免后续读写操作报错。
三、fscanf():读取文本文件内容
1. 基本语法
matlab
% 格式1:按指定格式读取全部内容
data = fscanf(fid, format);
% 格式2:指定读取数量(如读取N个数据)
[data, count] = fscanf(fid, format, size);
format:读取格式(核心),常用'%d'(整数)、'%f'(浮点数)、'%s'(字符串)、'%c'(字符)size:读取数量,如[m,n](读取m行n列)、Inf(读取全部内容)count:实际读取的元素个数(可选)
2. 场景1:读取纯数值文本文件
目标文件(data.txt)内容:
10 20 30
40 50 60
70 80 90
读取代码:
matlab
% 打开文件
[fid, msg] = fopen('data.txt', 'r');
if fid == -1
disp(msg);
return; % 打开失败则退出
end
% 按浮点数格式读取全部内容,转为3行3列矩阵
data = fscanf(fid, '%f', [3,3]);
data = data'; % 转置(fscanf默认按列存储,需转置匹配原文件行列)
% 关闭文件
fclose(fid);
% 输出结果
disp('读取的矩阵:');
disp(data);
输出结果:
读取的矩阵:
10 20 30
40 50 60
70 80 90
3. 场景2:读取混合格式文本文件
目标文件(info.txt)内容:
姓名:张三 年龄:25 成绩:92.5
姓名:李四 年龄:23 成绩:88.0
读取代码:
matlab
[fid, msg] = fopen('info.txt', 'r');
if fid == -1
disp(msg);
return;
end
% 循环读取每一行(feof(fid)判断是否到文件末尾)
while ~feof(fid)
% 按自定义格式读取:跳过固定字符,提取姓名、年龄、成绩
line = fscanf(fid, '姓名:%s 年龄:%d 成绩:%f\n', [1,3]);
% 解析数据
name = line{1};
age = line{2};
score = line{3};
% 输出
disp(['姓名:', name, ' 年龄:', num2str(age), ' 成绩:', num2str(score)]);
end
fclose(fid);
关键技巧 :feof(fid)是"文件末尾判断函数",返回1表示到末尾,0表示未到,适合循环读取多行文本。
4. 场景3:读取纯文本字符串(如日志文件)
目标文件(log.txt)内容:
2024-10-10 09:00:00 程序启动
2024-10-10 09:05:00 数据处理完成
2024-10-10 09:10:00 程序退出
读取代码:
matlab
[fid, msg] = fopen('log.txt', 'r');
if fid == -1
disp(msg);
return;
end
% 按字符读取全部内容(保留换行符)
log_content = fscanf(fid, '%c', Inf);
fclose(fid);
% 按换行符拆分每行
log_lines = strsplit(log_content, '\n');
% 遍历输出每行
for i = 1:length(log_lines)
if ~isempty(log_lines{i}) % 跳过空行
disp(['第', num2str(i), '行:', log_lines{i}]);
end
end
四、fprintf():写入内容到文本文件
1. 基本语法
matlab
count = fprintf(fid, format, A, B, ...);
count:写入的字符个数(可选)format:写入格式,与fscanf()一致,支持\n(换行)、\t(制表符)A,B,...:要写入的变量(数值、字符串均可)
2. 场景1:写入数值矩阵到文本文件
需求:将3x3矩阵按行列格式写入文件,保留1位小数。
matlab
% 准备数据
data = [1.23, 4.56, 7.89; 2.34, 5.67, 8.90; 3.45, 6.78, 9.01];
% 打开文件(写入模式,不存在则创建)
[fid, msg] = fopen('output.txt', 'w');
if fid == -1
disp(msg);
return;
end
% 循环写入每行
for i = 1:size(data, 1)
% 按格式写入:每行3个浮点数,保留1位小数,空格分隔,末尾换行
fprintf(fid, '%.1f %.1f %.1f\n', data(i,1), data(i,2), data(i,3));
end
% 关闭文件
fclose(fid);
disp('数据写入完成!');
生成的output.txt内容:
1.2 4.6 7.9
2.3 5.7 8.9
3.5 6.8 9.0
3. 场景2:追加内容到文本文件
需求:在上述output.txt末尾追加一行备注信息。
matlab
[fid, msg] = fopen('output.txt', 'a'); % 追加模式
if fid == -1
disp(msg);
return;
end
% 写入备注(字符串+当前时间)
fprintf(fid, '\n备注:数据生成时间 - %s\n', datestr(now()));
fclose(fid);
disp('备注追加完成!');
追加后的文件内容:
1.2 4.6 7.9
2.3 5.7 8.9
3.5 6.8 9.0
备注:数据生成时间 - 10-Oct-2024 15:30:00
4. 场景3:写入混合格式内容(字符串+数值)
需求:生成包含实验信息的文本文件,格式如下:
实验编号:EXP001
测试温度:25.5 ℃
测试次数:10 次
测试结果:[98.5, 97.8, 99.2]
实现代码:
matlab
exp_id = 'EXP001';
temp = 25.5;
test_times = 10;
results = [98.5, 97.8, 99.2];
[fid, msg] = fopen('exp_info.txt', 'w');
if fid == -1
disp(msg);
return;
end
% 按自定义格式写入
fprintf(fid, '实验编号:%s\n', exp_id);
fprintf(fid, '测试温度:%.1f ℃\n', temp);
fprintf(fid, '测试次数:%d 次\n', test_times);
fprintf(fid, '测试结果:[%.1f, %.1f, %.1f]\n', results(1), results(2), results(3));
fclose(fid);
disp('实验信息写入完成!');
五、fclose():关闭文件的"最后一步"
1. 基本语法
matlab
status = fclose(fid); % 关闭指定句柄的文件
status = fclose('all'); % 关闭所有打开的文件(推荐批量处理时用)
status:关闭状态,0表示成功,-1表示失败
2. 关键注意事项
- 无论读写是否成功,都必须执行
fclose(),否则会导致:- 文件被MATLAB占用,无法手动删除/修改;
- 写入的内容可能未完全保存(缓存未刷新);
- 打开的文件句柄过多,导致后续
fopen()失败。
- 批量处理文件时,用
fclose('all')避免遗漏关闭某个文件。
六、避坑指南:新手常见错误与解决方案
1. 坑1:文件路径错误导致fopen失败
- 现象:
fid=-1,错误信息提示"找不到文件"; - 原因:使用相对路径时,MATLAB当前工作目录不是文件所在目录;
- 解决方案:
- 用
pwd查看当前工作目录,cd切换到文件目录(如cd D:\test); - 直接使用绝对路径(如
'D:\test\data.txt')。
- 用
2. 坑2:fscanf读取矩阵时行列颠倒
- 现象:读取的矩阵行列与原文件相反;
- 原因:
fscanf默认按列存储数据; - 解决方案:读取后用
data = data'转置矩阵。
3. 坑3:写入文件后内容为空
- 现象:文件创建成功,但内容为空;
- 原因:未关闭文件(缓存未刷新),或写入格式错误;
- 解决方案:
- 确保执行
fclose(fid); - 检查
fprintf的格式符与变量类型匹配(如数值用%f,字符串用%s)。
- 确保执行
4. 坑4:覆盖原有文件导致数据丢失
- 现象:原有文件内容被清空;
- 原因:误使用
'w'模式打开文件; - 解决方案:
- 写入前确认文件是否需要保留,重要文件先备份;
- 追加内容用
'a'模式,而非'w'模式。
七、实战综合案例:批量处理文本数据
需求
读取多个实验数据文件(data1.txt、data2.txt、data3.txt),计算每个文件的平均值,将结果汇总写入result.txt。
实现代码
matlab
% 定义文件列表
file_list = {'data1.txt', 'data2.txt', 'data3.txt'};
% 打开汇总文件
[fid_result, msg] = fopen('result.txt', 'w');
if fid_result == -1
disp(msg);
return;
end
fprintf(fid_result, '实验文件\t平均值\n'); % 写入表头
% 遍历每个数据文件
for i = 1:length(file_list)
filename = file_list{i};
% 打开数据文件
[fid_data, msg_data] = fopen(filename, 'r');
if fid_data == -1
disp(['跳过文件', filename, ':', msg_data]);
fprintf(fid_result, '%s\t读取失败\n', filename);
continue;
end
% 读取数据并计算平均值
data = fscanf(fid_data, '%f', Inf);
avg = mean(data);
% 写入汇总文件
fprintf(fid_result, '%s\t%.2f\n', filename, avg);
% 关闭数据文件
fclose(fid_data);
end
% 关闭汇总文件
fclose(fid_result);
disp('批量处理完成,结果已写入result.txt!');