fgetl gets stuck in infinite loop

Hi,
I am new to programming and have an issue with my simulation (I 'inherited' the code). When I run the simulation, sometimes works ok, but sometimes it just stops (I don't get an error, but simulation is not proceeding). When I terminate simulation (ctr+c) I get an notification that tells me it stoped in fgetl(line 33). (see the sctreen shot)
I tried pausing and restarting the simulation, terminating it and restarting (sometimes that works, sometimes it stops again, but not in the same step), restarting comupter ...
Does anyone have an idea what is going on? I'm using MATLAB R2016a.
Here is a code of the program that 'error' occurs:
function getmcml2(name, Nz,Nr)
% function getmcml2(name)
global Rd Rr Rsp Td A Azr Az
fid = fopen(name,'r');
line = fgetl(fid);
while(isempty(strfind(line,'RAT')))
line = fgetl(fid);
end
line = fgetl(fid);
while(isempty(strfind(line,'RAT')))
line = fgetl(fid);
end
line = fgetl(fid);
Rsp = sscanf(line,'%f'); %disp(sprintf('\tRsp = %f', Rsp))
line = fgetl(fid);
Rd = sscanf(line,'%f'); %disp(sprintf('\tRd = %f', Rd))
line = fgetl(fid);
A = sscanf(line,'%f'); %disp(sprintf('\tA = %f', A))
line = fgetl(fid);
Td = sscanf(line,'%f'); %disp(sprintf('\tT = %f', Td))
while(isempty(strfind(line,'A_z')))
line = fgetl(fid);
end
Az = fscanf(fid,'%f');
while(isempty(strfind(line,'Rd_r')))
line = fgetl(fid);
end
Rr = fscanf(fid,'%f');
while(isempty(strfind(line,'A_rz')))
line = fgetl(fid);
end
u = fscanf(fid,'%f');
Azr = reshape(u, [Nz Nr]);
fclose(fid);
clear fid

5 Comments

When you control-C a program, you interrupt it the next time the MATLAB interpreter gets control. The "Operation terminated" tells you where it happened to get interrupted.
This does not in any way mean that the program was "stuck" in fgetl(): it can just mean that the program does a lot of fgetl() compared to other operations, so that statistically it was more likely you would terminate there than at other lines.
We don't see your code how you called the fgetl, in it, there's an example on its usage. Also, the file might be too large so it takes a lot of time to read it. Code snippet would be useful.
% Example
fid=fopen('textfile.txt');
while 1
tline = fgetl(fid);
if ~ischar(tline), break, end
disp(tline)
end
fclose(fid);
Neat alternative, but your code might need the adjustment
fileData = splitlines(fileread('textfile.txt')); % returns a cell with character arrays
On File Exchange, there's also submission readfile that can detect file encoding and properly read the files (if you face some character issues, use this).
FGETL is not the problem. If this function reads a lot of data from the disk, there is a certain chance to stop Matlab during it runs.
Why do you assume, that the simulation is not proceeding?
Julija Snezak
Julija Snezak on 5 Feb 2021
Edited: Julija Snezak on 5 Feb 2021
@Jan: Before I terminate the simulation it can be on the same Run (like in the picture, without red line) for hours. When it is running, one run takes maybe a second.
@Mario Malic I think file is not too big, because on the same set of data, sometimes simulation is finished, but sometimes it gets stuck.
function getmcml2(name, Nz,Nr)
% function getmcml2(name)
global Rd Rr Rsp Td A Azr Az
fid = fopen(name,'r');
line = fgetl(fid);
while(isempty(strfind(line,'RAT')))
line = fgetl(fid);
end
line = fgetl(fid);
while(isempty(strfind(line,'RAT')))
line = fgetl(fid);
end
line = fgetl(fid);
Rsp = sscanf(line,'%f'); %disp(sprintf('\tRsp = %f', Rsp))
line = fgetl(fid);
Rd = sscanf(line,'%f'); %disp(sprintf('\tRd = %f', Rd))
line = fgetl(fid);
A = sscanf(line,'%f'); %disp(sprintf('\tA = %f', A))
line = fgetl(fid);
Td = sscanf(line,'%f'); %disp(sprintf('\tT = %f', Td))
while(isempty(strfind(line,'A_z')))
line = fgetl(fid);
end
Az = fscanf(fid,'%f');
while(isempty(strfind(line,'Rd_r')))
line = fgetl(fid);
end
Rr = fscanf(fid,'%f');
while(isempty(strfind(line,'A_rz')))
line = fgetl(fid);
end
u = fscanf(fid,'%f');
Azr = reshape(u, [Nz Nr]);
fclose(fid);
clear fid

Sign in to comment.

Answers (1)

while(isempty(strfind(line,'A_z')))
line = fgetl(fid);
end
This code stucks in an infinite loop, if a file does not contain the substring 'A_z' in the expected location.
A safer method to search for a string:
try
...
key = 'A_z';
while ~contains(line, key)
line = fgetl(fid);
end
Az = fscanf(fid,'%f');
key = 'Rd_r';
while ~contains(line, key)
line = fgetl(fid);
end
Rr = fscanf(fid,'%f');
...
catch ME
error(['Tools:', mfilename, ':BadFile'], 'Failed to find [%s] in: %s', key, name);
end
By the way, it is a fragile programming style to provide the outputs using global variabels. Prefer to use output arguments instead. Remember, that any other program, which uses global variables with hte same name, will be deeply confused.
Hint: fgets ist faster than fgetl, which calls fgets internally and spends time to crop the line break.
Using clear to remove variabels is a waste of time in Matlab in most cases.

1 Comment

Julija Snezak
Julija Snezak on 9 Feb 2021
Edited: Julija Snezak on 9 Feb 2021
Thank you for the anwsers! I will try your suggestion on changing the code. And thank you for the advice on fgets and global variables.
EDIT: contains only works for 2016b and more recent. I changed it with strfind.

Sign in to comment.

Categories

Tags

Asked:

on 5 Feb 2021

Edited:

on 9 Feb 2021

Community Treasure Hunt

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

Start Hunting!