【问题标题】:MATLAB - Read Textfile (lines with different formats) line by lineMATLAB - 逐行读取文本文件(不同格式的行)
【发布时间】:2017-12-29 13:40:57
【问题描述】:

我有一个这种类型的文本文件(我们称之为输入文件):

%我的输入文件类型 % Comment 1 % Comment 2

4 %参数F

2.745 5.222 4.888 1.234 %参数X

273.15 373.15 1 %温度初始/最终/步骤

3.5 %参数Y

%矩阵A

1.1 1.3 1 1.05

2.0 1.5 3.1 2.1

1.3 1.2 1.5 1.6

1.3 2.2 1.7 1.4

我需要读取这个文件并将值保存为变量,甚至更好地保存为不同数组的一部分。例如通过阅读我应该得到Array1.F=4;然后Array1.X应该是3个实数的向量,Array2.Y=3.5然后Array2.A是一个矩阵FxF。有很多函数可以从文本文件中读取,但我不知道如何读取这些不同的格式。我过去使用fgetl/fgets 读取行,但它读取为字符串,我使用过fscanf,但它读取整个文本文件,就好像它的格式都是一样的。但是,我需要使用预定义格式按顺序阅读的内容。我可以很容易地用 fortran 逐行读取来做到这一点,因为 read 有一个格式语句。 MATLAB中的等价物是什么?

【问题讨论】:

  • textscan 允许您读取指定数量的行,这不会倒回文件指针。这允许具有不同格式规范的顺序读取。
  • 我不完全理解您所说的“不倒带文件指针”是什么意思,您能更好地向我解释一下吗?此外,在 C = textscan(FID,'FORMAT',N) 从文件中读取数据时,使用 FORMAT N 次,其中 N 是正整数。要在 N 个循环后从文件中读取其他数据,请使用原始 FID 再次调用 textscan。是告诉行数的N参数吗?像 N=1 那样逐行读取?

标签: matlab text-files scanf textscan


【解决方案1】:

这实际上会解析您在示例中发布的文件。我本可以做得更好,但我今天累了:

res = struct();

fid = fopen('test.txt','r');
read_mat = false;

while (~feof(fid))
    % Read text line by line...
    line = strtrim(fgets(fid));

    if (isempty(line))
        continue;
    end

    if (read_mat) % If I'm reading the final matrix...
        % I use a regex to capture the values...
        mat_line = regexp(line,'(-?(?:\d*\.)?\d+)+','tokens');

        % If the regex succeeds I insert the values in the matrix...
        if (~isempty(mat_line))
            res.A = [res.A; str2double([mat_line{:}])];
            continue; 
        end
    else % If I'm not reading the final matrix...
        % I use a regex to check if the line matches F and Y parameters...
        param_single = regexp(line,'^(-?(?:\d*\.)?\d+) %Parameter (F|Y)$','tokens');

        % If the regex succeeds I assign the values...
        if (~isempty(param_single))
            param_single = param_single{1};
            res.(param_single{2}) = str2double(param_single{1});
            continue; 
        end

        % I use a regex to check if the line matches X parameters...
        param_x = regexp(line,'^((?:-?(?:\d*\.)?\d+ ){4})%Parameter X$','tokens');

        % If the regex succeeds I assign the values...
        if (~isempty(param_x))
            param_x = param_x{1};
            res.X = str2double(strsplit(strtrim(param_x{1}),' '));
            continue; 
        end

        % If the line indicates that the matrix starts I set my loop so that it reads the final matrix...
        if (strcmp(line,'%Matrix A'))
            res.A = [];
            read_mat = true;
            continue;
        end
    end
end

fclose(fid);

【讨论】:

  • 非常感谢您的帮助,因为有些行我不知道,请问您是否可以编辑并在每个部分仅添加几个 cmets 来解释您在做什么每个部分?
猜你喜欢
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多