【C++、Matlab】VS2013 C++读写.mat文件

本文介绍如何利用C++读写Matlab的.mat文件,包括环境配置步骤、关键函数解析及代码实例,帮助读者理解跨语言数据交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fishing-panhttps://blog.youkuaiyun.com/u013921430转载请注明出处】

前言

      Matlab是一个非常强大的工具,为我们平时的学习和工作提供了非常大的便利。Matlab不仅自身功能强大,还为其他语言提供了接口,早前的学习中需要用的C++读写.mat文件,今天将当时的学习心得分享给大家,希望对大家有所帮助。

软件工具:VS2013+Matlab2016a+Win7(X64)

工程配置

1. 添加环境变量

      因为要用到Matlab的自带的库,所以需要将Matlab中库所在的目录添加到环境变量中

      将以下路径添加到环境变量中

      F:\matlab2016a_exe\extern\lib\win64

      F:\matlab2016a_exe\extern\lib\win64\microsoft

      然后重启电脑(路径根据你的安装路径有所调整)

2.创建VS项目并配置管理器

    在创建一个VS新项目后,默认是win32的项目,但是由于我的Matlab是x64的,所以需要重新配置管理器;

点击配置管理器,然后再在弹框中选择新建,最后选择x64即可;

3. 项目属性

     右键项目,在弹出的最后一项中选择属性

      

选择 C/C++ ——>常规——>附加包含目录

输入以下路径,点击确定按钮

再下滑选择链接器——>常规——>附加库包含目录

输入以下路径

点击确定,然后下滑选择输入——>附加依赖项

输入以下四个库:

  1. libmat.lib
  2. libmx.lib
  3. libmex.lib
  4. libeng.lib

最后点击确定

编写代码

为了方便展示,在此先将C++代码展示给大家,方便后续的展开讲解;

代码

#include <mat.h>
#include <iostream>


using namespace std;

double mat_read(string path, string name, mxArray *&Array1, mxArray *&Array2)
{
	MATFile *pmatFile = matOpen((path + "\\" + name + ".mat").c_str(), "r");
	if (pmatFile == NULL)
		cout << "MatOpen error!!!" << endl;

	Array1 = matGetVariable(pmatFile, "length");
	Array2 = matGetVariable(pmatFile, "tracts");

	matClose(pmatFile);
	return 0;
}


int main()
{
	mxArray *Array1 = NULL;
	mxArray *Array2 = NULL;
	string filepath = "G:\\博客\\C++获取mat数据\\CPPgetMat\\CPPgetMat";
	string filename = "InputTest";
	mat_read(filepath, filename, Array1, Array2);

	int64_T *dim = (int64_T *)(mxGetDimensions(Array1));
	//int *Dim = (int*)dim;
	int ss = mxGetNumberOfDimensions(Array1);
	int pp = mxGetM(Array1);
	cout <<"数据有"<< ss << "维度"<<endl;
	for (int i = 0; i < ss;i++)
	{
		cout << "第" << (i + 1) << "维度的大小是" << dim[i] << endl;
	}

	double *Data = (double*)mxGetData(Array1);
	
	cout <<"Data[0]的值是"<< Data[0] << endl;


	double *out = new double[6];
	for (int i = 0; i < 2;i++)
	{
		for (int j = 0; j < 3; j++)
		{
			out[i*3+j] = 5 * j + i;
		}
	}
	


	MATFile *OutFile = NULL;
	mxArray *pMxArray = NULL;

	OutFile = matOpen("G:\\博客\\C++获取mat数据\\CPPgetMat\\CPPgetMat\\outTest.mat", "w");
	pMxArray = mxCreateDoubleMatrix(2, 3, mxREAL);
	//mxSetData(pMxArray, (mxArray *)out);
	memcpy((void *)(mxGetPr(pMxArray)), (void *)out, sizeof(double)*6);
	
	Data = (double*)mxGetData(pMxArray);

	//cout << Data[4] << endl;
	matPutVariable(OutFile, "test", pMxArray);

	system("pause");
	return 0;
}

输出

输出结果

输出数据

我们来看看读入的数据,

数据中有两个数据成员变量lengthtracts;

变量length的内容为

 

代码分析

读入mat文件的代码分析

1. 使用matOpen函数打开mat文件

 MATFile *matOpen(const char *filename,const char *mode)

filename:文件路径和名称(.mat文件)

mode:打开文件的三种模式

r:以只读方式打开

u:更新模式,可读可写,但是如果要打开的数据文件不存在,也不会创建新的文件

w:以写入方式打开,只能写如入,如果要打开的数据文件不存在,则创建一个新的文件;

2. 使用matGetVariable函数读取mat文件中的变量

mxArray * matGetVariable(MATFile * pMF, const char *name); 

读取名为name的变量,返回一个数据阵列指针

pMF:指向所读入的文件的指针;

name:文件中名为name的变量,该变量必须是已存在的;

3. 使用mxGetDimensions获取数据维度

const size_t *mxGetDimensions(const mxArray *pa);

获取数据的各个维度的大小并返回的维度保存在一个数组中;

此外还可以使用mxGetMmxGetN函数获取数据阵列矩阵的维数

size_t mxGetM(const mxArray *pa);

第一维,也就是矩阵有多少行

size_t mxGetN(const mxArray *pa);

第二维,也就是矩阵有多少列,若是多维数组,则返回其他所有维度的乘积。

4. 使用mxGetData函数获取数据阵列中的数据

void *mxGetData(const mxArray *pa );    

由于返回值是void的,所以需要进行强制的返回类型说明,返回类型根据Matlab中变量存储的类型确定。

注意:无论mat的维度是多少,在C++中均是1维的数据,并且数组的第一个编号是1,所以在赋值给新数组时候,需要减去1

从上面的输出结果看出,C++中的第一个元素编号是0,而在Matlab中第一个元素的编号是1;所以Data[0]=40;

5. 使用mxGetNumberOfDimensions获取维度数量

 int  mxGetNumberOfDimensions(const mxArray *array_ptr);
返回维度的数量,比如length的维度数量为2;

写出.mat文件的代码分析                     

1. 使用matOpen函数打开mat文件

   见上文

2.  使用mxCreateDoubleMatrix创建数组

mxArray *mxCreateDoubleMatrix(size_t m, size_t n, mxComplexity flag);

创建一个m行,n列的数组,flag处一般填写mxReal即可,表示是实数,还可以填写mxCOMPLEX;

3. 使用memcpy进行数值拷贝

在早前版本的matlab自带的版本中使用的是mxSetData函数进行数值输入,但是在比较新的版本中,这个函数使用会出现错误,笔者也不知道为什么。所以在不确定的情况下,你可以使用memcpy;

//mxSetData(pMxArray, (mxArray *)out);
memcpy((void *)(mxGetPr(pMxArray)), (void *)out, sizeof(double)*6);

同读出数据一样,写入数据也需要注意以下问题

注意:输入的数组out必须是1维的,而且Matlab是按存储的,这与C++中按照存储不同,所以我们原本输出应该是

0,5,10;1,6,11;却变成了我们所看到的结果中的0,10,6;5,1,11;

有疑问的可以尝试使用Matlab中的reshape函数;

4. 使用matPutVariable将变量放入文件中

matError matPutVariable(MATFile * pMF, const char * name, const mxArray * pA);

pMF:指向所读入的文件的指针;

name:文件中名为name的变量,若该变量名已存在的,则会被覆盖;

pA:被写入的变量;

如果写入成功则会返回0,如果写入失败则返回非0;

5. 关于内存释放

 

    有的博客中写到完成mat文件操作后需要调用matClose函数关闭文件,并使用mxFree释放内存

    但是,笔者在写入数据后,尝试使用matClose函数关闭被打开的文件和使用mxFree函数释放内存时,出现了释放内存的错误,这可能是版本不同的原因,读者按照自己的Matlab版本酌情处理。

本博客撰写参考了以下博客,特说明,深表感谢;

http://blog.youkuaiyun.com/left_la/article/details/8206645

 

 

 

 

 

 
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值