Problem extracting data out of a variable of mat file in C++

I have to extract the data out of a variable(double array) of a mat file for use in my C++ code.I have tried the mxGetPr, mxGetVariable and mxGetData functions but they do not seem to work.I am able to read the mat file and even get the variable's name and no. of rows and columns but I haven't been able to extract data.Please help me out ,need urgent help!!

2 Comments

Please post you code so we can point out the errors and suggest corrections.
Here is my code -I have actually modified the matlab diagnose mat file code and added the getvariable command to extract the data.
#include <stdio.h>
#include <stdlib.h>
#include "mat.h"
#include "matrix.h"
#include "mex.h"
#include <iostream>
int diagnose(const char *file) {
MATFile *pmat;
const char **dir;
const char *a;
int ndir;
int i;
mxArray *pa;
double *pr;
printf("Reading file %s...\n\n", file);
/*
* Open file to get directory
*/
pmat = matOpen(file, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", file);
return(1);
}
/*
* get directory of MAT-file
*/
dir = (const char **)matGetDir(pmat, &ndir);
if (dir == NULL) {
printf("Error reading directory of file %s\n", file);
return(1);
} else {
printf("Directory of %s:\n", file);
for (i=0; i < ndir; i++)
printf("%s\n",dir[i]);
}
mxFree(dir);
/* Read in each array. */
printf("\nReading in the actual array contents:\n");
/*Get Variable*/
pa = matGetVariable(pmat, file);
//I donot know how to get the variable pointed to by pointer 'pa'
and use it in my C++ code.
int main(int argc, char **argv)
{
int result;
if (argc > 1)
result = diagnose(argv[1]);
else{
result = 0;
printf("Usage: matdgns <matfile>");
printf(" where <matfile> is the name of the MAT-file");
printf(" to be diagnosed\n");
}
return (result==0)?EXIT_SUCCESS:EXIT_FAILURE;
}

Sign in to comment.

Answers (1)

Your incorrect code:
/*Get Variable*/
pa = matGetVariable(pmat, file);
The 2nd argument is supposed to be the variable name, not the file name. E.g.,
/*Get Variable*/
pa = matGetVariable(pmat, dir[i]);
Then you can get at the data using mxGetPr(pa) etc. Just be sure not to free dir before you are done with it. And when you are done with it, free each dir[i] first since all of these strings are dynamically allocated also.

9 Comments

/* Read in each array. */
for (i=0; i<ndir; i++) {
printf("\nReading in the actual array contents:\n");
pa = matGetVariable(pmat, dir[i]);
pr =mxGetPr(pa);
printf("element data = %d\n",*pr);
int total_num_of_elements = mxGetNumberOfElements(pa);
printf("size is %d\n",total_num_of_elements );
if(mxIsNumeric(pa))
{ printf("Data is numeric\n");}
m= mxGetM (pa);
printf("rows is %d\n",m);
l= mxGetN(pa);
printf("columns is %d\n",l);
mxFree(dir);
}
}
int main(int argc, char **argv)
{
int result;
if (argc > 1)
result = diagnose(argv[1]);
else{
result = 0;
printf("Usage: matdgns <matfile>");
printf(" where <matfile> is the name of the MAT-file");
printf(" to be diagnosed\n");
}
return (result==0)?EXIT_SUCCESS:EXIT_FAILURE;
}
but now the output is:
Reading file file.mat...
Directory of file.mat:
s
Reading in the actual array contents:
element data=0
size is 2
data is numeric
rows is 1
columns is 2
I cannot find the problem in this code-Thanking you in advance.
"... Just be sure not to free dir before you are done with it. ..."
You did not follow these instructions. You have mxFree(dir) inside your loop, so after the first iteration dir is no longer valid. Then on the 2nd iteration through the loop you access dir[i], which is invalid because you just free'd dir on the previous iteration.
Solution: You can put mxFree(dir[i]) inside your loop at the end (but not inside the mxIsNumeric(pa) check) to free the individual name strings, but you cannot have mxFree(dir) inside the loop. You need to move that outside the loop.
Thank you for your reply but putting mxFree(dir[i]) inside the loop at the end (not inside the mxIsNumeric(pa) check) gives error C2664: 'mxFree' : cannot convert parameter 1 from 'const char *' to 'void *' - n putting mxFree(dir) outside the loop gives the same output I mentioned above. Any help would be appreciated.
That's because you declared it to be const for some reason. Change this:
const char **dir;
to this:
char **dir;
ok now I changed const char to char and made the necessary changes ,but now the code compiles but stops working while debugging upon coming to the command mxFree(dir{i]). If I use mxFree(dir) outside the loop the output is the same with element data =0
I took a closer look at the matGetDir function and looked at all the addresses returned for the pointers and strings used and have come to the conclusion that I was wrong about the individual string allocations. It turns out that the pointer array and the strings themselves are all part of one big contiguous memory block. Everything is sitting behind the dir address. So get rid of the mxFree(dir[i]) stuff completely. Just have one mxFree(dir) call at the end of your code (outside the loop).
Thank you so much for the time you spent on my code.Ok now my code is:
/* Read in each array. */
for (i=0; i<ndir; i++) {
printf("\nReading in the actual array contents:\n");
pa = matGetVariable(pmat, dir[i]);
int total_num_of_elements = mxGetNumberOfElements(pa);
printf("size is %d\n",total_num_of_elements );
if(mxIsNumeric(pa))
{ printf("Data is numeric\n");}
m= mxGetM (pa);
printf("rows is %d\n",m);
l= mxGetN(pa);
printf("columns is %d\n",l);
pr =mxGetPr(pa);
printf("element data = %d\n",*pr);}//end of for loop
printf("done\n");
mxFree(dir);
}
But the problem remains the same, element data =0, I think there is some problem with the mxGetPr function, and also I do not understand why does the for loop outputs are displayed once,I mean the mat file has a row vector s=[1 2] .Your timely help will be greatly appreciated Sir.
The %d format specifier indicates an integer argument, but I do not think the compiler converts the double *pr to int.
Try casting *pr from a double to an int datatype. For example:
...%d\n",(int)(*pr));
You only see one element because you are not iterating over the #elements in the array (the variable l).
This stack overflow article goes into some detail regarding the printf issue:
Thank you Ketan for your timely help, the casting solved my issue. I am really grateful to your help on my question .

Sign in to comment.

Asked:

on 26 Jun 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!