Converting text file to struct

21 次查看(过去 30 天)
Leos Pohl
Leos Pohl 2021-7-19
评论: Jan 2021-7-20
I am trying to read values from text file into a struct. The original assignement to a struct was like this:
C.fname_dem = '~/somewhere/matlab_code/SOMEFILE.IMG';
C.lines_n = 7200;
C.scale_factor = 0.5;
C.origin = [3600 3600];
C.phi_max = 2.*pi;
C.t_duration = 30*24*3600;
C.a = 6.957e8;
The input text file "constants.txt" looks like this:
fname_dem = '~/somewhere/matlab_code/SOMEFILE.IMG'
lines_n = 7200
scale_factor = 0.5
origin = [3600 3600]
% important comment
phi_max = 2.*pi
t_duration = 30*24*3600
a = 6.957e8
The code that i have come up with is below. It basically first reads all into an array (or cell array, i am not sure i ever understand the difference in matlab), removing comment type lines and whitespaces. The second loop should be an attempt to convert things like '30*24*3600' into expressions. It almost works with the exception '2*pi` is not probably understood and myStruct.phi_max returns 2*pi. Second, for non array-values, this gives [1×1 sym], instead of a value (I am not sure whether this is a problem:
fname_dem: "'~/somewhere/matlab_code/SOMEFILE.IMG'"
lines_n: [1×1 sym]
scale_factor: [1×1 sym]
origin: [1×2 sym]
phi_max: [1×1 sym]
t_duration: [1×1 sym]
a: [1×1 sym]
What can i do to make these appear as values, not as [1×1 sym] or [1×2 sym] but correctly as e.g. origin: [3600 3600] (I have found that if they are displayed as [1x1 sym], matlab does not tread those as numbers) and how to make sure that the line with pi works?
The code:
fid = fopen('constants.txt');
i = 1;
lines = string.empty;
while ~feof(fid)
tline = fgetl(fid);
tline = strtrim(tline);
if tline(1) == '%'
continue
end
line = split(tline, '=');
lines(i,1) = strtrim(line{1});
lines(i,2) = strtrim(line{2});
i = i + 1;
end
for i = 1:length(lines)
if extractBefore(lines(i,2),2) ~= "'"
myStruct(lines(i,1)) = str2sym(lines(i,2));
else
myStruct(lines(i,1)) = lines(i,2);
end
end

回答(1 个)

Jan
Jan 2021-7-20
编辑:Jan 2021-7-20
Your text file is almost valid Matlab code: only the trailing semicolons are removed. Now you try to write some code, which interpretes and evaluates the text. This is a reinventing of a Matlab code interpreter. So the best way woudl be to convert ther text file to a valid Matlab function:
function C = yourData
C.fname_dem = '~/somewhere/matlab_code/SOMEFILE.IMG';
C.lines_n = 7200;
C.scale_factor = 0.5;
C.origin = [3600 3600];
% important comment;
C.phi_max = 2.*pi;
C.t_duration = 30*24*3600;
C.a = 6.957e8;
end
Then execute the function to obtain C. The conversion can be done automaticlly:
T = fileread('constants.txt');
C = strtrim(strsplit(T, '\n'));
isCode = ~strncmp(C, '%', 1);
C(isCode) = strcat('C.', C(isCode), ';');
mFile = fullfile(cd, 'constants.m');
[fid, msg] = fopen(mFile, 'w');
assert(fid ~= -1, msg);
fprintf(fid, 'function C = constants\n');
fprintf('%s\n', C{:});
fprintf('end\n');
fclose(fid);
Avoid to re-invent a Matlab interpreter.
  2 个评论
Leos Pohl
Leos Pohl 2021-7-20
Let me make sure that i understand. I have the file 'constants.txt', the compiled program reads it, builds a function from that and executes that. If I make changes to 'constants.txt' there will be no need to rebuild?
(also, I think the 2 lines before the last should look like:
fprintf(fid,'%s\n', C{:});
fprintf(fid,'end\n');
)
Jan
Jan 2021-7-20
Oh, you are talking about a compiled application. This is another story. It might be possible to execute the code an eval(), but this could be a conflict with the license conditions. A compiled application, which is a pseudo-Matlab-interpreter is not covered by the license agreement, as far as I understand.
Is it really required to provide data in the form of "[3600 3600]", "2.*pi" and "30*24*3600"?

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 String Parsing 的更多信息

产品


版本

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by