我有一个文件,其中包含以下信息:
% ---------------------- location details --------------------------
%
% lat : latitude [minimum = -90, maximum = 90, unit =
% degrees north]
% lon : longitude [ minimum = -360, maximum = 360, unit =
% deg east]
% z: altitude (above sea level, m)
%---------------------------------------------------------------
% location:
lat = 54.35
lon = -2.9833
这是文件的一小部分。
我想将这些信息读入MATLAB,然后可以使用这些信息进行一些计算。我想要读入MATLAB的文件部分是文本文件中没有注释的部分,即在行的开头有一个%
,变量应该是然后保存在工作区中。例如,我想:
lat = 54.35
lon = -2.9833
在工作区中。
我该怎么做?我读过关于textscan
和fopen
的内容,虽然在这种情况下这些似乎并不能帮助我。
答案 0 :(得分:4)
我能想到的最简单的解决方案是读取这个文件确实使用textscan
:)并且由于这些行是用有效的MATLAB语法编写的,所以稍后可以使用eval
来评估它们。首先将每一行读作一个字符串(忽略标题中的注释)
fid = fopen(filename);
C = textscan(fid, '%s', 'Delimiter', '', 'CommentStyle', '%')
fclose(fid);
然后将这些行逐个输入eval
以在MATLAB工作区中创建变量:
cellfun(@eval, C{1});
这样做是将该行解释为MATLAB命令,即创建文件中指定的变量并分配适当的值。如果您想要取消eval
的输出,可以使用evalc
代替“吸收输出”:
cellfun(@evalc, C{1}, 'UniformOutput', false);
这应该适用于您的基本示例,但如果您有任何参数的多个实例,它将失败。另请注意,eval
家庭的速度非常慢。
如果文件结构中的行具有parameter name = number
模式,则可以更智能地读取行:
fid = fopen(filename);
C = textscan(fid, '%[^= ]%*[= ]%f', 'CommentStyle', '%')
fclose(fid);
模式中的%[^= ]
与第一个字符匹配,直到第一个空格或等号。 %*[ =]
忽略等号和任何尾随空格,然后数值与%f
匹配。生成的单元格数组C
将参数名称存储在第一个单元格中,并将其对应的值存储在第二个单元格中。
现在由您来操作已解析的数据。例如,要提取lat
和lon
的所有值,您可以执行以下操作:
lat = C{2}(strcmp(C{1}, 'lat'));
lon = C{2}(strcmp(C{1}, 'lon'));
如果您有多个“lat”行,lat
将是一个包含所有这些值的数组。
答案 1 :(得分:0)
这是另一种快速而又肮脏的方式:
fp = fopen('foo.txt');
found = 1;
while ~feof(fp)
line = fgetl(fp);
if (line(1) ~= '%') && ischar(line)
value(found) = sscanf(line,'%*s %*s %f');
found = found + 1;
end
end
%*s
跳过'lat'或'long'和'='。
答案 2 :(得分:0)
您提供的示例有点表现良好,因此以下解决方案可能需要一些剪裁。但是,我建议针对任何eval()
:
% Read whole file ignoring lines that start with '%' and using '=' as delimiter
fid = fopen('test.txt');
s = textscan(fid,'%s%f', 'CommentStyle','%','Delimiter','=');
fclose(fid);
% Identify lines with latitude and those with longitude
idxLat = strncmpi('lat',s{1},3);
idxLon = strncmpi('lon',s{1},3);
% Store all latitudes and longitudes
lat = s{2}(idxLat);
lon = s{2}(idxLon);
答案 3 :(得分:0)
获取一个字段名称与参数名称匹配的结构,接受以逗号分隔的列表。列出在char_params
中应保留为字符串的所有参数char_params={};
fid = fopen(filename);
% Load lines into cell (1x1) containing cell array s (Nx1),
% skipping lines starting with % and cutting off anything after % in a line
s = textscan(fid,'%s', 'CommentStyle','%','Delimiter','%');
fclose(fid);
% access the lines strings s{1}, split across '=' and remove whitespace on both sides
s=strtrim(split(s{1},'='));
% Interpret parameters and save to structure
for ind=1:length(s)
% User says which parameters are strings
if any(strcmpi(s{ind,1},char_params))
file_struct.(s{ind,1})=s{ind,2};
% Otherwise, assume they are numbers or numeric row arrays
else
% remove parentheses and brackets
trim_s=regexprep(s(ind,2),'[[]()]','');
% convert comma-separated lists into row arrays
file_struct.(s{ind,1})=str2double(split(trim_s{1},',')).';
end
end