beginh
beginh

Reputation: 1153

how to read a structure from .txt file in matlab

I want to ask you for help in what follows: I have couple of structures saved in a .txt file and I want to read them in matlab and save in a convenient type to load them later on into a .mat file. I've been searching through the internet to find a solution but what I got was info about reading columns, specific strings... but I cannot combine it to get the answer I want. Any help appreciated! Thanks a lot!

here code I'm trying to work on:

struct
studentname: joe
notes:
n1 = 1.3
n2 = 2.0
average =1.7
endstruct

struct
studentname : marc
notes:
n1 = 2.3 %commentary, to be ommitted while reading from the file
n2 = 3.0
average = 2.7
endstruct

Upvotes: 2

Views: 4762

Answers (3)

Amro
Amro

Reputation: 124563

Here a complete solution (similar to what @Marc described):

%# read lines
fid = fopen('file.txt','rt');
C = textscan(fid, '%s', 'Delimiter',''); C = C{1};
fclose(fid);

%# start/end of each structure
startIdx = find(ismember(C, 'struct'));
endIdx = find(ismember(C, 'endstruct'));

%# array of strucutres
N = numel(startIdx);
arr = struct('studentname','', 'notes','', 'n1',0, 'n2',0, 'average',0);
arr = repmat(arr,[N 1]);

%# parse and store each structure in the array
for i=1:numel(startIdx)
    %# parse key/value of struct
    s = C(startIdx(i)+1:endIdx(i)-1);
    s = regexp(s, '(\w+)\s*[:=]\s*([^%$]*)(?:%[^$]*)?', 'tokens', 'once');
    s = vertcat(s{:});

    %# try to parse as numbers
    v = str2double(s(:,2));
    s(~isnan(v),2) = num2cell(v(~isnan(v)));

    %# store: struct.key = value
    for j=1:size(s,1)
        arr(i).(s{j,1}) = s{j,2};
    end
end

The result:

>> arr(1)
ans = 
    studentname: 'joe'
          notes: ''
             n1: 1.3
             n2: 2
        average: 1.7
>> arr(2)
ans = 
    studentname: 'marc'
          notes: ''
             n1: 2.3
             n2: 3
        average: 2.7

Of course this assumes the file is well formatted (struct/endstruct blocks, all structs contain the same fields, and field types are consistent)


Explanation:

The code starts by reading the file lines into a cell array. Then we look for the start/end position of struct/endstruct constructs. We initialize an empty array of structure with some default values, and we iterate through the file parsing each block, and storing that info in one structure.

Next we use regular expression to detect the following pattern:

some_key_name = some value  % optional comment here

we allow for some variations in spaces, and also accept either = or : as character in between. We use capturing tokens in regexp to recover each component of the above, and store them in a temporary cell array. At this point, everything is stored as strings.

Now that actual values can either be numeric or strings. We initially try to parse them as numbers using STR2DOUBLE. This function returns NaN if it fails, which we use to change only the parts that were successfully converted.

Finally with the above result, we use dynamic field names to store each value in the corresponding key inside the structure array.

Upvotes: 4

Marc
Marc

Reputation: 3313

Unfortunately, you are basically going to have to roll your own. You can start with fileread(), which reads the entire file into a string, then, reading line by line, maybe using regexp() or strfind() to parse each line, then finally using either struct() or dynamic field access to construct your structs.

Untested, incomplete, but rough idea (presumes file is well-formed - you will need to add checks):

%read file
wholeFile = fileread(myfilename);

%find starts & ends:
starts = strfind(wholeFile, 'struct');
ends = strfind(wholeFile, 'endstruct');

For i = 1:numel(starts);
    rawStruct = wholeFile(starts(i)+7, ends(i)-2);
    %parse line by line getting field names using the string "rawStruct"
    out(i).(fieldname) = content;
end

Upvotes: 1

Maurits
Maurits

Reputation: 2114

You could give the XML_io_tools from the Matlab file exchange a try. It can parse a XML file to a matlab struct and visa versa.

Upvotes: -2

Related Questions