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構造体の開始/終了位置を探します。構造体の空の配列をいくつかのデフォルト値で初期化し、ファイルを反復処理して各ブロックを解析し、その情報を1つの構造体に格納します。

次に、正規 表現を使用して次のパターンを検出します。

some_key_name = some value  % optional comment here

=スペースのバリエーションを考慮し、または:その間の文字としても受け入れます。正規表現でキャプチャトークンを使用して、上記の各コンポーネントを回復し、一時セル配列に格納します。この時点で、すべてが文字列として保存されます。

これで、実際の値は数値または文字列のいずれかになります。最初に、STR2DOUBLEを使用してそれらを数値として解析しようとします。この関数はNaN、失敗した場合に返されます。これは、正常に変換された部分のみを変更するために使用されます。

最後に、上記の結果で、動的フィールド名を使用して、構造体配列内の対応するキーに各値を格納します。

于 2012-06-04T17:46:24.240 に答える
1

残念ながら、基本的には自分でロールする必要があります。から始めてfileread()、ファイル全体を文字列に読み取り、次に行ごとに読み取り、regexp()またはを使用strfind()して各行を解析し、最後にまたはのいずれstruct()かを使用しdynamic 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 に答える