一、安装matio库
matio库是一个用于读取和写入MAT文件(MATLAB数据格式)的开源C库。它提供了一组函数和工具,使得在C和C++程序中可以方便地读取和写入MAT文件中的数据。MAT文件是MATLAB软件中常用的文件格式,用于存储多维数值数组、结构体、字符数据等。
在ubuntu20.04系统中,可以直接使用命令行apt工具获取matio库。依次执行以下步骤即可:
1、更新系统包列表
sudo apt update
2、安装matio库
sudo apt install libmatio-dev
3、验证安装
pkg-config --modversion matio
二、利用gcc编译
如需要使用使用matio库,需要对gcc命令添加额外的参数。
1、正常情况下,编译名为test.c的C语言源码文件需要命令行输入:
gcc test.c
这样,在test.c相同文件夹下,生成默认的可执行文件a.out。在相同文件夹下命令行执行
./a.out
即可运行程序。
2、如果需要指定可执行文件的名称,则需要如下操作
gcc test.c -o name
生成了名称为name的可执行文件。
./name
可以运行程序。
3、但是,如果应用了matio库,则需要对gcc命令添加额外的参数。由于Ubuntu中的C/C++库文件是被存放在/usr/lib或者/usr/lib/x86_64-linux-gnu中的(也可能是其他位置)。所以编译的时候需要手动链接外部库。指令如下:
gcc test.c /usr/lib/libmatio.a -o name
其中,libmatio.a即为matio库文件。
4、然而,为了省去搜索外部库位置的操作,可以直接用以下命令代替上述操作
gcc test.c -lmatio -o name
注意,-lmatio和手动输入库位置,是完全等价的。
三、C语言中如何使用matio库
1、包含matio库头文件:在你的代码中,使用#include
指令包含matio库的头文件。例如,如果要读取MAT文件,可以在代码中添加以下行:
#include <matio.h>
2、打开MAT文件:在代码中使用Mat_Open()
函数打开MAT文件。该函数返回一个指向mat_t
类型结构体的指针,该结构体包含有关MAT文件的信息。例如,要打开名为example.mat
的MAT文件,可以使用以下代码:
mat_t *matfp;
matfp = Mat_Open("example.mat", MAT_ACC_RDONLY);
请注意,MAT_ACC_RDONLY
表示只读访问模式,如果需要写入数据到MAT文件,请使用MAT_ACC_RDWR
访问模式。
3、读取变量:在MAT文件中,变量存储在结构体中。需要使用Mat_VarRead()
函数读取结构体变量,该函数返回一个指向matvar_t
类型结构体的指针。例如,要读取名为myvar
的MAT变量,可以使用以下代码:
matvar_t *matvar;
matvar = Mat_VarRead(matfp, "myvar");
注意,Mat_VarRead函数的第二个参数需要指定MAT变量的名称,如果名称未知,可以使用Mat_ReadNext()函数
while ((matvar = Mat_VarReadNext(matfp)) != NULL)
{
// 在这里处理matvar,例如打印变量名称
printf("变量名称:%s\n", matvar->name);
// 释放matvar的内存
Mat_VarFree(matvar);
}
注意,释放matvar的内存非常重要。由于matvar只是一个结构体指针,被重新赋值的时候,原来指向的内存空间不会被释放,这会造成内存泄漏!
4、释放资源:在完成读取任务后,需要释放打开的MAT文件和读取的变量。可以使用Mat_VarFree()
函数释放变量,使用Mat_Close()
函数关闭MAT文件。例如,可以使用以下代码来释放资源:
Mat_VarFree(matvar);
Mat_Close(matfp);
四、示例代码
#include <stdio.h>
#include <matio.h>
static double** p_target_array=NULL;
int main(void)
{
mat_t* p_mat_info;
p_mat_info=Mat_Open("Image_letter_E.mat",MAT_ACC_RDONLY);
if (p_mat_info==NULL)
{
printf("open failed!\n");
return 1;
}
matvar_t* p_mat_var;
p_mat_var=Mat_VarReadNext(p_mat_info);
int rank;
rank=(int)p_mat_var->rank;
size_t* dims;
dims=(size_t*)p_mat_var->dims;
double* data=(double*)p_mat_var->data;
p_target_array=(double**)calloc(dims[0],8);
for(int i=0;i<dims[0];i++)
{
p_target_array[i]=(double*)calloc(dims[1],8);
for (int j=0;j<dims[1];j++)
{
p_target_array[i][j]=data[i*dims[0]+j];
}
}
Mat_VarFree(p_mat_var);
Mat_Close(p_mat_info);
printf("%f",p_target_array[0][0]);
return 0;
}
matvar_t结构体有哪些成员变量,可以上网搜索。需要注意的是,像我这样读取一个double类型的矩阵,虽然矩阵是二维的。但matvar_t的成员变量其实还是一个一维的数组。需要手动展开为二维的数组。