Converting text file to struct

16 views (last 30 days)
Leos Pohl
Leos Pohl on 19 Jul 2021
Commented: Jan on 20 Jul 2021
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

Answers (1)

Jan
Jan on 20 Jul 2021
Edited: Jan on 20 Jul 2021
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 Comments
Leos Pohl
Leos Pohl on 20 Jul 2021
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 on 20 Jul 2021
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"?

Sign in to comment.

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!