0

这是一个后续问题

将文本文件中的参数读入工作区

我想知道,我将如何阅读以下内容:

% ---------------------- details --------------------------
%---------------------------------------------------------------
% location:
   lat = 54.35
   lon = -2.9833
%

Eitan T 建议使用:

fid = fopen(filename);
C = textscan(fid, '%[^= ]%*[= ]%f', 'CommentStyle', '%')
fclose(fid);

从文件中获取信息,然后

lat = C{2}(strcmp(C{1}, 'lat'));
lon = C{2}(strcmp(C{1}, 'lon'));

获取相关参数。我怎么能改变这个来阅读以下内容:

% ---------------------- details --------------------------
%---------------------------------------------------------------
% location:
   lat = 54.35
   lon = -2.9833
   heights = 0, 2, 4, 7, 10, 13, 16, 19, 22, 25, 30, 35
   Volume = 6197333, 5630000, 4958800, 4419400, 3880000, 3340600,   
        3146800, 2780200, 2413600, 2177000, 1696000, 811000
%

变量应该包含等号后面的所有数据点(直到下一个变量的开始,在这种情况下为 Volume)?

谢谢你的帮助

4

3 回答 3

2

这是一种方法,它使用一些肮脏的字符串黑客攻击并eval获得结果。这适用于您的示例,但我不会真正推荐它:

fid = fopen('data.txt');
contents = textscan(fid, '%s', 'CommentStyle', '%', 'Delimiter', '\n');
contents = contents{1};

for ii = 1:length(contents)
  line = contents{ii};
  eval( [strrep(line, '=', '=['), '];'] ) # convert to valid Matlab syntax
end

更好的方法是使用读取每一行textscan

for ii = 1:length(contents)
  idx = strfind(contents{ii}, ' = ');
  vars{ii} = contents{ii}(1:idx-1);
  vals(ii) = textscan(contents{ii}(idx+3:end), '%f', 'Delimiter', ',');
end

现在变量varsvals具有变量的名称及其值。要提取值,您可以执行以下操作

ix = strmatch('lat', vars, 'exact');
lat = vals{ix};

ix = strmatch('lon', vars, 'exact');
lon = vals{ix};

ix = strmatch('heights', vars, 'exact');
heights = vals{ix};

ix = strmatch('Volume', vars, 'exact');
volume = vals{ix};
于 2013-06-04T09:39:15.787 回答
1

这可以使用两步方法来完成:

  1. 读取前导字符串(第一个元素),等号(忽略),并将该行的其余部分作为字符串(第二个元素)
  2. 将这些字符串的其余行转换为浮点数(第二个元素)

然而,这里有一个小缺点;你的台词似乎遵循两种格式;一个是步骤 1) 中描述的那个,另一个是前一行的延续,其中包含数字。

因此,需要一个额外的步骤:

  1. 读取前导字符串(第一个元素),等号(忽略),并将该行的其余部分作为字符串(第二个元素)
  2. 当遇到“其他格式”时,这将失败。检测到这一点,纠正这一点,然后继续
  3. 将这些字符串的其余行转换为浮点数(第二个元素)

我认为这可以解决问题:

fid = fopen('data.txt');

C = [];
try
    while ~feof(fid)

        % Read next set of data, assuming the "first format"
        C_new = textscan(fid, '%[^= ]%*[= ]%s', 'CommentStyle', '%', 'Delimiter', '');
        C     = [C; C_new]; %#ok

        % When we have non-trivial data, check for the "second format"
        if ~all(cellfun('isempty', C_new))

            % Second format detected!
            if ~feof(fid)

                % get the line manually
                D = fgetl(fid);
                % Insert new data from fgetl
                C{2}(end) = {[C{2}{end} C{1}{end} D]};
                % Correct the cell
                C{1}(end) = [];

            end

        else
            % empty means we've reached the end
            C = C(1:end-1,:);

        end

    end
    fclose(fid);

catch ME
    % Just to make sure to not have any file handles lingering about
    fclose(fid);
    throw(ME);

end

% convert second elements to floats
C{2} = cellfun(@str2num, C{2}, 'UniformOutput', false);
于 2013-06-04T12:25:27.960 回答
0

如果你可以摆脱多行卷线,你写的是有效的matlab。因此,只需使用run命令将参数文件作为 matlab 脚本调用。

run(scriptName)

正如其他人所表明的那样,您唯一的其他选择是编写最终看起来像一个混蛋的 Matlab 解析器。绝对有比这样做更好的消磨时间的方法!

于 2013-06-04T16:15:14.687 回答