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

4 篇文章 3 订阅

fishing-panhttps://blog.csdn.net/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.csdn.net/left_la/article/details/8206645

 

 

 

 

 

 
  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
要在C++读写MATLABMAT文件,可以使用MATLAB C++ API。这个API可以让你在你的C++程序调用MATLAB引擎,并且使用MATLAB引擎来读写MAT文件。下面是一些基本的步骤: 1. 安装MATLAB引擎API,这通常可以在MATLAB的安装目录下找到。 2. 在你的C++程序包含MATLAB引擎API的头文件。 3. 创建MATLAB引擎对象并启动它。 4. 使用MATLAB引擎对象来读取MAT文件的数据。 5. 使用MATLAB引擎对象来写入数据到MAT文件。 下面是一些示例代码,可以帮助你开始使用MATLAB引擎API: ```c++ #include "mat.h" #include "engine.h" #include <iostream> int main() { // 启动MATLAB引擎 Engine* eng = engOpen(NULL); if (!eng) { std::cout << "无法启动MATLAB引擎" << std::endl; return 1; } // 读取MAT文件的变量 mxArray* data = matGetVariable(eng, "filename.mat", "variablename"); if (!data) { std::cout << "无法读取MAT文件的变量" << std::endl; return 1; } // 使用变量 // ... // 写入数据到MAT文件 matPutVariable(eng, "filename.mat", "variablename", data); // 释放资源 mxDestroyArray(data); engClose(eng); return 0; } ``` 在这个示例,我们启动了MATLAB引擎,然后使用`matGetVariable`函数来读取MAT文件的变量。我们可以使用返回的`mxArray`对象来访问这个变量的数据。然后,我们使用`matPutVariable`函数将修改后的变量写入MAT文件。最后,我们释放了使用的资源,并关闭MATLAB引擎。 注意,这只是一个简单的示例,实际情况下可能需要更多的代码来处理错误和异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值