虽然MATLAB将字符数组和字符串,字符串数组进行了区分,但是出于兼容性考虑,在下面的各种输入输出方式中无论是使用字符数组还是字符串都是一样的效果。

显示变量的值

disp函数可以用来显示一个变量的值,如果这个变量是字符串的话,也可以达到输出信息的效果,但是会自动添加一个回车。

例如

1
2
disp('hello,world!');
% hello,world!

这里的disp(X)语句加不加;都是一样的。

disp函数只接受一个参数,我们可以将字符数组拼接起来进行显示

1
2
disp(['hello', ',', 'world']);
% hello,world

在很多默认行为中都会调用disp函数,例如一个普通的赋值语句如果不以;结尾,可能会对赋值结果调用disp函数以展示它的值。

格式化字符串

MATLAB支持和C语言几乎一样的字符串格式化函数,包括fprintfsprintf

fprintf格式化输出到控制台或文件中,返回值只是输出的字节数,没什么用,例如

1
2
3
4
5
fprintf('Hello, %s!\n', 'World'); % 缺省时输出到控制台
Hello, World!

fileID = fopen('exp.txt','w'); % 打开文件
fprintf(fileID,'Hello, %s!\n', 'World'); % 写入文件中

sprintf格式化输出到一个字符串,返回值就是格式化得到的字符串,例如

1
2
3
4
5
6
name = 'Alice';
age = 30;
height = 5.5;
str = sprintf('Name: %s, Age: %d, Height: %.1f feet', name, age, height);

disp(str);

文件读写

在 MATLAB 中,文件打开模式与 C 语言非常类似。

使用fopen函数打开文件,除了文件名之外,还可以指定不同的模式来控制文件的读写行为,常见的文件打开模式包括:

  • r:只读模式。文件必须存在,否则会出错。
  • w:写入模式。如果文件存在,将覆盖文件;如果文件不存在,将创建新文件。
  • a:追加模式。如果文件存在,数据将写入文件末尾;如果文件不存在,将创建新文件。
  • r+:读写模式。文件必须存在,否则会出错。
  • w+:读写模式。如果文件存在,将覆盖文件;如果文件不存在,将创建新文件。
  • a+:读写模式。如果文件存在,数据将写入文件末尾;如果文件不存在,将创建新文件。

此外,还可以指定文本模式或二进制模式:

  • t:文本模式(默认)。
  • b:二进制模式。

fopen函数返回的是文件ID,后续对这个文件的操作都需要传入文件ID,包括最后的关闭文件fclose

下面列举几个常见的文件操作:

逐行读取文本并展示

1
2
3
4
5
6
7
8
fileID = fopen('example.txt', 'r');

while ~feof(fileID)
line = fgetl(fileID);
disp(line);
end

fclose(fileID);

逐行写入文本

1
2
3
4
5
6
fileID = fopen('output.txt', 'w');

fprintf(fileID, 'This is a test.\n');
fprintf(fileID, 'The value of pi is approximately %.4f\n', pi);

fclose(fileID);

写入二进制文件

1
2
3
4
5
6
7
fileID = fopen('binaryoutput.bin', 'wb');

data = [1.1, 2.2, 3.3];

fwrite(fileID, data, 'double'); % 以double格式写入

fclose(fileID);

读取二进制文件,这里重新读取出来的data变成列向量了。

1
2
3
4
5
6
7
fileID = fopen('binaryoutput.bin', 'rb');

data = fread(fileID, 'double'); % 以double格式读取

disp(data);

fclose(fileID);

MAT文件读写

MATLAB 专门提供 saveload 函数,用于保存和加载 .mat 文件,这是一种 MATLAB 特有的二进制文件格式,可以完整存储工作空间中的变量,包括变量的类型、大小和其他元数据。

保存变量

使用save函数可以直接把当前工作区的所有变量保存到MAT文件中

1
save('all_data.mat')

我们也可以将指定的部分变量保存到MAT文件中

1
2
3
p = rand(1,10);
q = ones(10);
save("pqfile.mat","p","q")

可以以追加形式把数据添加到MAT文件中

1
2
3
D = ones(2);

save("mydata.mat", "D", "-append")

注意:

  • 如果文件已经存在,默认会直接覆盖原始文件,除非加上-append选项;
  • load命令其实需要一个格式选项,默认是-mat,也支持-ascii等其他格式,但是对文本格式的操作不够灵活,建议使用fprintf;对格式的判断与文件后缀名无关。

可以使用whos命令查看MAT文件当前存储的变量列表,得到的是一个结构体数组

1
2
fileInfo = whos("-file", "mydata.mat");
disp(fileInfo);

可以加上-struct选项解包一个结构体数组,将其中的所有字段作为单独变量存储到MAT文件中

1
2
3
4
s1.a = 12.7;
s1.b = {"abc",[4 5; 6 7]};
s1.c = "Hello!";
save("newstruct.mat","-struct","s1")

可以加上MAT文件的格式版本,默认7.0版本,但是只有7.3版本可以支持超过2GB的数据

1
2
3
A = rand(5);
B = magic(10);
save("example.mat","A","B","-v7.3")

可以使用-nocompression选项,这个选项会阻止存储过程中的压缩,优点是存储过程更快,缺点是MAT文件变大

1
2
3
A = rand(5);
B = magic(10);
save("example.mat","A","B","-v7.3","-nocompression")

一个常见的需求是,MAT文件中已经存储了我们关注的若干变量,我们希望使用工作区中的同名变量更新MAT文件中的数据,但是不引入工作区中的其他变量

1
2
existingVars = whos("-file","mydata.mat");
save("mydata.mat",existingVars.name)

加载变量

使用load函数可以直接把MAT文件中的所有变量加载到工作区中

1
load('mydata.mat');

也可以指定加载MAT文件中的部分变量到工作区中(这里甚至支持通过正则匹配加载满足的部分变量)

1
load('mydata.mat', 'var1', 'var2', ...);

注意:

  • 如果当前工作区的变量和MAT文件中的变量重复,那么MAT文件中的变量值就会直接覆盖它!
  • 在加载MAT文件时我们可能需要传递文件格式,默认格式是-mat,也支持-ascii等选项,格式的判断与文件后缀无关;

我们可以使用变量接受load的返回值,这样会把所有变量加载到一个结构体数组中,作为结构体数组的字段,而不是直接暴露在工作区中

1
2
3
4
data = load('mydata.mat');

disp(data.A);
disp(data.B);