2

我想在以下方面向您寻求帮助:我有几个结构保存在 .txt 文件中,我想在 matlab 中读取它们并保存为方便的类型,以便稍后将它们加载到 .mat 文件中。我一直在互联网上搜索以找到解决方案,但我得到的是关于阅读列、特定字符串的信息......但我无法将它结合起来得到我想要的答案。任何帮助表示赞赏!非常感谢!

这是我正在尝试处理的代码:

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
4

3 回答 3

4

这是一个完整的解决方案(类似于@Marc描述的):

%# 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

结果:

>> 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

当然这是假设文件格式正确(struct/endstruct 块,所有结构都包含相同的字段,并且字段类型是一致的)


解释:

代码首先将文件行读入一个元胞数组。然后我们寻找 struct/endstruct 结构的开始/结束位置。我们用一些默认值初始化一个空的结构数组,并遍历文件解析每个块,并将该信息存储在一个结构中。

接下来我们使用正则 表达式来检测以下模式:

some_key_name = some value  % optional comment here

我们允许空间中的一些变化,并且也接受两者之间的任何一个=:作为字符。我们在正则表达式中使用捕获标记来恢复上述每个组件,并将它们存储在一个临时元胞数组中。此时,所有内容都存储为字符串。

现在实际值可以是数字或字符串。我们最初尝试使用 STR2DOUBLE 将它们解析为数字。NaN如果失败,此函数将返回,我们使用它仅更改成功转换的部分。

最后有了上面的结果,我们使用动态的字段名将每个值存储在结构体数组中对应的键中。

于 2012-06-04T17:46:24.240 回答
1

不幸的是,您基本上将不得不自己动手。您可以从 开始fileread(),它将整个文件读入一个字符串,然后逐行读取,可能使用regexp()orstrfind()解析每一行,最后使用struct()ordynamic field access来构造您的结构。

未经测试,不完整,但粗略的想法(假设文件格式正确 - 您需要添加检查):

%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
于 2012-06-04T12:57:54.553 回答
-2

您可以尝试使用 Matlab 文件交换中的XML_io_tools。它可以将 XML 文件解析为 matlab 结构,反之亦然。

于 2012-06-04T12:28:53.880 回答