Convert C code to Matlab code for reading binary file

3 views (last 30 days)
I'm looking for help reading a binary file in the most efficient way (fast). Here is the C-code. Thanks.
#define MAX_LAYERS 100
typedef struct
{
char string[1000];
} STRINGARRAY_STRUCT;
typedef struct
{
double rangeFinals;
double crossFinals;
STRINGARRAY_STRUCT time[MAX_LAYERS]; // Sample: xx:xx:xx
double dir[MAX_LAYERS]; // degrees
double speed[MAX_LAYERS]; // knots
int flagSpeed[MAX_LAYERS]; // flag speed
int flagDir[MAX_LAYERS]; // flag direction
int flagTime[MAX_LAYERS]; // flag time
int percentTraversed;
int year[MAX_WIND_LAYERS];
int jDay[MAX_WIND_LAYERS];
} CURRENT_STRUCT;
typedef struct
{
char string[1000];
} STRINGARRAY_STRUCT;
int main (int argc, char **argv)
{
FILE *fp;
CURRENT_STRUCT winds;
fp = fopen (FileName, "rb");
if (fp != NULL)
{
fread (&winds, sizeof(CURRENT_STRUCT), 1, fp);
fclose (fp);
}
}
  1 Comment
Mike D.
Mike D. on 21 Mar 2023
I allocated a blank structure like this:
s = struct('DR',0,'CR',0,'layers',char(zeros(100,100)), ...
'winddir',NaN(100,1),'windspeed',NaN(100,1), ...
'flagSpeed',uint8(0),'flagDir',uint8(0),'flagTime',uint8(0), ...
'traversed',uint8(0),'year',uint8(ones(100,1)),'jday',uint8(ones(100,1)));
But what is the fread syntax after doing fopen?

Sign in to comment.

Answers (1)

Les Beckham
Les Beckham on 21 Mar 2023
Your Matlab struct doesn't match the definition in the C code. For example, the third element is a char array of 100x1000 in the C code and a 100x100 array in the Matlab code, flagDir and flagTime are arrays in the C code (of some unknown length, since you didn't show the definition of MAX_WIND_LAYERS), but scalar in the Matlab code. Also, some of the names don't match, which may or may not be an issue.
If you provide a sample of the data file it will be easier to get an accurate answer.
I think you are going to have to read the struct in pieces and copy those pieces into your struct.
For example:
rangeFinals = fread(fp, 1, 'double');
crossFinals = fread(fp, 1, 'double');
time = fread(fp, [100, 1000], 'char');
...
s.rangeFinals = rangeFinals;
s.crossFinals = crossFinals;
...
  2 Comments
Mike D.
Mike D. on 21 Mar 2023
Thanks for the comments. Yea, I noticed the 100x1000 issue and the different names and MAX_WIND_LAYERS is supposed to be MAX_LAYERS. These things are easy fixes. I'm more concerned about the overall structure and how to efficiently read the data. I currently have it like you say:
s(i).DR = fread(app.fileID,1,'double');
s(i).CR = fread(app.fileID,1,'double');
for j = 1 : 100
s(i).layers(j,:) = fread(app.fileID,1000,'char');
end
s(i).dir = fread(app.fileID,100,'double');
s(i).speed = fread(app.fileID,100,'double');
s(i).flagSpeed = fread(app.fileID,100,'uint8');
s(i).flagDir = fread(app.fileID,100,'uint8');
s(i).flagTime = fread(app.fileID,100,'uint8');
s(i).transversed = fread(app.fileID,1,'uint8');
s(i).year = fread(app.fileID,100,'uint8');
s(i).jday = fread(app.fileID,100,'uint8');
I just thought there might be an easier way (less code) and faster more efficient way, such as a one-liner with fread given the structure format.
Les Beckham
Les Beckham on 21 Mar 2023
Unfortunately, I don't think you can do it all at once in Matlab like you can in C.

Sign in to comment.

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!