/********************************************************************************************* Description: 提供基本matlab读写数据功能 Copyright : All right reserved by ZheYuan.BJ Author : Zhang Zhonghai Date : 2023/09/18 ***********************************************************************************************/ #include #include #include #include #include "matlab_io.h" using namespace std; // 将matlab存储方式转换成c存储方式 #define TRANS_ROW_COL(dst, src, rowNum, colNum) \ for (int rowI = 0; rowI < rowNum; ++rowI) { \ for (int colJ = 0; colJ < colNum; ++colJ) { \ dst[rowI * colNum + colJ] = src[colJ * rowNum + rowI]; \ } \ } /* 读取结构体中的二维字符串矩阵(一维的cell,每个cell又有一层cell,每个cell是一个字符串)*/ bool ReadChildString2D(const string& filePath, const string& parentName, const string& selfName, vector >& vvStr) { MATFile* pMatFile = nullptr; mxArray* pMxArray = nullptr; mxArray* pCell = nullptr; int rowNum, colNum; char strBuf[STRING_BUF_SIZE]; pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件 if (pMatFile == nullptr) { cout << "filePath is error!" << endl; return false; } mxArray* pMxParent = matGetVariable(pMatFile, parentName.c_str()); //获取G变量 // 读取字符串 pMxArray = mxGetField(pMxParent, 0, selfName.c_str()); // ds rowNum = (int)mxGetM(pMxArray); colNum = (int)mxGetN(pMxArray); for (int i = 0; i < rowNum; ++i) { for (int j = 0; j < colNum; ++j) { pCell = mxGetCell(pMxArray, j * rowNum + i); int childRowNum = (int)mxGetM(pCell); int childColNum = (int)mxGetN(pCell); vvStr.push_back(vector()); vvStr.back().resize(childRowNum * childColNum); for (int ii = 0; ii < childRowNum; ii++) { for (int jj = 0; jj < childColNum; jj++) { mxArray* pChildCell = mxGetCell(pCell, jj * childRowNum + ii); if (mxGetString(pChildCell, strBuf, STRING_BUF_SIZE) != 0) { cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl; return false; } vvStr.back()[ii * childColNum + jj] = strBuf; // auto& lastStr = vvStr.back()[ii * childColNum + jj]; // transform(lastStr.begin(), lastStr.end(), lastStr.begin(), ::toupper); // 转成大写 } } } } mxDestroyArray(pMxArray); return true; } /* 读取结构体中的二维double矩阵(一维的cell,每个cell又有一层cell,每个cell是一个字符串)*/ bool ReadChildDouble2D(const string& filePath, const string& parentName, const string& selfName, vector >& vvDouble) { MATFile* pMatFile = nullptr; mxArray* pMxArray = nullptr; mxArray* pCell = nullptr; int rowNum, colNum; pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件 if (pMatFile == nullptr) { cout << "filePath is error!" << endl; return false; } mxArray* pMxParent = matGetVariable(pMatFile, parentName.c_str()); //获取G变量 // 读取double数据 pMxArray = mxGetField(pMxParent, 0, selfName.c_str()); // ds rowNum = (int)mxGetM(pMxArray); colNum = (int)mxGetN(pMxArray); for (int i = 0; i < rowNum; ++i) { for (int j = 0; j < colNum; ++j) { pCell = mxGetCell(pMxArray, j * rowNum + i); int childRowNum = (int)mxGetM(pCell); int childColNum = (int)mxGetN(pCell); vvDouble.push_back(vector()); vvDouble.back().resize(childRowNum * childColNum); double* pVal = (double*)mxGetData(pCell); //获取指针 TRANS_ROW_COL(vvDouble.back(), pVal, childRowNum, childColNum); // 行列存储方式转换 } } mxDestroyArray(pMxArray); return true; } /* 读取字符串矩阵 */ bool ReadMtxString(const string& filePath, const string& mtxName, vector& vStr, int* pRowNum, int* pColNum) { MATFile* pMatFile = nullptr; mxArray* pMxArray = nullptr; mxArray* pCell = nullptr; int rowNum, colNum; char strBuf[STRING_BUF_SIZE]; pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件 if (pMatFile == nullptr) { cout << "filePath is error!" << endl; return false; } pMxArray = matGetVariable(pMatFile, mtxName.c_str()); //获取.mat文件里面名为matrixName的矩阵 rowNum = (int)mxGetM(pMxArray); colNum = (int)mxGetN(pMxArray); vStr.resize(rowNum * colNum); for (int i = 0; i < rowNum; ++i) { for (int j = 0; j < colNum; ++j) { pCell = mxGetCell(pMxArray, j * rowNum + i); if (mxGetString(pCell, strBuf, STRING_BUF_SIZE) != 0) { cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl; return false; } vStr[i * colNum + j] = strBuf; } } *pRowNum = rowNum; *pColNum = colNum; return true; } /* 从mat文件中读取给定名称的矩阵数据,并获取矩阵的行列数值 */ T* ReadMtxDouble(const string& filePath, const string& mtxName, int* pRowNum, int* pColNum) { T* dst = nullptr; MATFile* pMatFile = nullptr; mxArray* pMxArray = nullptr; int rowNum, colNum; double* matData; pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件 if (pMatFile == nullptr) { cout << "filePath is error!" << endl; return nullptr; } pMxArray = matGetVariable(pMatFile, mtxName.c_str()); //获取.mat文件里面名为matrixName的矩阵 rowNum = (int)mxGetM(pMxArray); colNum = (int)mxGetN(pMxArray); // cout << rowNum << " " << colNum << endl; matData = (double*)mxGetData(pMxArray); //获取指针 dst = new T[rowNum * colNum]; for (int i = 0; i < rowNum; ++i) { for (int j = 0; j < colNum; ++j) { dst[i * colNum + j] = T(matData[j * rowNum + i]); } } mxDestroyArray(pMxArray); //释放内存 matClose(pMatFile); // 关闭文件 *pRowNum = rowNum; *pColNum = colNum; return dst; } /* 将数据写入mat文件中,用给定的名称命名 */ bool SaveMtxDouble(T* src, MATFile* pMatFile, string matrixName, int rowNum, int colNum) { //转置存储 int datasize = colNum * rowNum; double* mtxData = new double[datasize];//待存储数据转为double格式 // memset(mtxData, 0, datasize * sizeof(double)); if (pMatFile == nullptr) { cout << "mat file pointer is error!" << endl; return false; } for (int i = 0; i < rowNum; i++) { for (int j = 0; j < colNum; j++) { mtxData[j * rowNum + i] = double(src[i * colNum + j]); // *(mtxData + j * rowNum + i) = (double)src[i * colNum + j]; 可消除警告 } } mxArray* pWriteArray = NULL;//matlab格式矩阵 //创建一个rowNum*colNum的矩阵 pWriteArray = mxCreateDoubleMatrix(rowNum, colNum, mxREAL); //把data的值赋给pWriteArray指针 memcpy((void*)(mxGetPr(pWriteArray)), (void*)mtxData, sizeof(double) * datasize); //给矩阵命名为matrixName matPutVariable(pMatFile, matrixName.c_str(), pWriteArray); mxDestroyArray(pWriteArray);//release resource delete[]mtxData;//release resource return true; }