fprintf modifying txt file in the wrong way

I have a code that changes a string in a separate txt file, however, after I use fprintf to replace an older parameter with a new one (calculated in my code), it seems to forget to break the line, resulting in a single string, which causes errors when I try to use this txt file elsewhere.
Whenever I open the modified txt file, the formatting seems visually ok, but ABAQUS (external solver I'm using) does not recognize the file in the same way as it's visualized.
*HYPERELASTIC, MOONEY-RIVLIN
95,30,0.0
This is the txt file as seen inside MATLAB after the string has been replaced
PROCESSING PART, INSTANCE, AND ASSEMBLY INFORMATION
*******************************************************
***ERROR: Problem when parsing keyword: HYPERELASTIC Invalid parameter:
MOONEY-RIVLIN
95. The parameter may be misspelled, obsolete, or
invalid.
***NOTE: DUE TO AN INPUT ERROR THE ANALYSIS PRE-PROCESSOR HAS BEEN UNABLE TO
INTERPRET SOME DATA. SUBSEQUENT ERRORS MAY BE CAUSED BY THIS OMISSION
END PROCESSING PART, INSTANCE, AND ASSEMBLY INFORMATION
***********************************************************
This is a raw copy/paste from the ABAQUS output - ABAQUS finds that 95 is in the same line as MOONEY-RIVLIN, which is not the case.
This is the part of the code that replaces the string
function e=disfunfem(x)
parC01=x(1);
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Changing the input files
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
s = fileread('material.inp');
position=strfind(s,'HYPERELASTIC');
begg=position+28;
num=begg;
endd=1;
while endd<begg
if s(num)==','
endd=num-1;
end
num=num+1;
end
% Replacing the modulus of elasticity
oldE=s(begg:endd);
putE=num2str(parC01);
s1=strrep(s,oldE,putE);
f_fil=fopen('material.inp','w');
fprintf(f_fil,s1);
fclose(f_fil);

Answers (2)

Rik
Rik on 24 Oct 2022
If it's a sufficiently old program, it might expect a carriage return along with a line end.
I would suggest reading the file with fileread, performing the replacement, and using the t switch for fopen to enable text mode. That might solve it.

1 Comment

I've tried adding that 't' parameter to the write function, but no luck.
A line break is missing somewhere, but I can't seem to find it.

Sign in to comment.

You can replace:
f_fil=fopen('material.inp');
s=fscanf(f_fil,'%c');
fclose(f_fil);
by
s = fileread('material.inp');
readlines and writelines would be more handy also.
It would be useful if you post the original file and explain, what you want to change.
What is the purpose of "begg=position+28" and the contents of parC01?
I assume the problem is hidden in the line breaks. If ABAQUS expects CHAR[13,10] as delimiter of lines and you have overwritten the 10, the confusion is invisible. The code can be simplified and this will fix this problem also.

4 Comments

I've tried simply replacing those 3 lines you've mentioned with fileread() but it generates the same error.
What is the purpose of "begg=position+28" and the contents of parC01?
begg is the starting position of the string I want to replace and parC01 is the parameter that is calculated elsewhere in the code, transformed into a string and replaced.
I do also believe that a line break is missing somewhere, but I just can't seem to figure out where.
"I've tried simply replacing those 3 lines" - Please post the file by attaching it. The part you have posted consists of 2 lines only. So which "3" lines do you want to replace by what?
"parC01 is the parameter" - it matters if it is an integer or floating point values. num2str is a smart function, which tries to guess the output format. Use sprintf for a specific conversion.
If you post the original file and explain explicitely, what you want to change, a much shorter and simpler solution can be provided. Post the file as attachment, such that we can check the line breaks. Posting it as text is an option also, but the line breaks vanish. Screen shots are the worst method to post text.
It is much easier to re-write the code from scratch than to fix the obviozusly buggy:
position=strfind(s,'HYPERELASTIC');
begg=position+28;
num=begg;
endd=1;
while endd<begg
if s(num)==','
endd=num-1;
end
num=num+1;
end
oldE=s(begg:endd);
Is this just thought to locate the "95"?
I've added the rest of the code on the original post. Every thing below the last line posted is related to Abaqus interaction with MATLAB, so it was cut for simplicity's sake.
I've replaced
f_fil=fopen('material.inp');
s=fscanf(f_fil,'%c');
fclose(f_fil);
With
s = fileread('material.inp');
The code that you've quoted is to find the position where 95 (or any other number) starts in the material.inp file and search for the end of that number, so it can be replaced.
@Luiz Simioni: Please attach the original file, such that we can test suggestions for a stable method to replace this number.
% [UNTESTED CODE]
function disfunfem(x)
% What is the output "e" in function e=disfunfem(x)?
s = readlines('material.inp');
p = find(startsWith(s, '*HYPERELASTIC'));
assert(numel(p) == 1, 'File contains no or more than one Keywords');
splitLine = strsplit(s(p + 1), ',');
s(p + 1) = strjoin([x(1), splitLine(2:end)], ",")
writelines('material.inp', s);
end

Sign in to comment.

Products

Release

R2022a

Asked:

on 24 Oct 2022

Commented:

Jan
on 25 Oct 2022

Community Treasure Hunt

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

Start Hunting!