MATLAB Answers

fprintf can't make new line

10 views (last 30 days)
I want to edit a line of a text file (tcl file actually). I tried with following code:
A = 5;
tcl = regexp(fileread('old_file.tcl'), '\n', 'split')';
tcl{3} = char(strcat("set A ",num2str(A),".0"));
fid = fopen('new_file.tcl','w');
fprintf(fid,'%s\n',tcl{:});
fclose(fid);
But it can't create new line after line 3. Instead, it create a character looks like small circle with black background, shown in figure below. I tried using fid==1 to check, it works fine in command window. How do I fix this? And if there is inefficiency in my code, suggestions are really appreciated. Thanks in advance.

  0 Comments

Sign in to comment.

Accepted Answer

Stephen Cobeldick
Stephen Cobeldick on 22 Feb 2020
Edited: Stephen Cobeldick on 22 Feb 2020
Try opening the file in text mode, not binary mode:
A = 5;
tcl = regexp(fileread('old_file.tcl'), '[\n\r]+', 'split')';
tcl{3} = sprintf('set A %u.0',A);
fid = fopen('new_file.tcl','wt'); % text mode!
fprintf(fid,'%s\n',tcl{:});
fclose(fid);

  6 Comments

Show 3 older comments
Stephen Cobeldick
Stephen Cobeldick on 22 Feb 2020
The .tcl file you uploaded uses Windows-style EOL characters, i.e. carriage return + linefeed (aka "newline"), often represented as \r\n (ASCII 13 and 10 respectively). When you split this at each newline character then each cell of tcl will end with the carriage return character:
>> double(tcl{1}(end))
ans =
13
You then add a character vector to cell 50, whose last character is a newline. Because you fopen-ed Truss3.tcl using text mode, that newline gets converted back to Windows-style carriage return + newline (see line 50 below):
Note how the other lines simply use the literal text that was stored in the cell array tcl. This is because, according to the fopen documentation, the carriage return character (at the end of each character vector) is not handled in any special way (only the newline character is).
This means that your output file uses inconsistent and rather unusual EOL characters. Classic Mac OS used carriage return as the EOL character, but I haven't seen a file like that for many years.
With a few small changes, you can easily create a file which uses consistent EOL characters as the original file (e.g. Windows-style, if you are using Windows):
A = 5;
tcl = regexp(fileread('Truss.tcl'), '\r?\n', 'split')'; % '\r?\n'
tcl{50} = sprintf('set A %u.0',A);
fid = fopen('Truss4.tcl','wt'); % must be text mode!
fprintf(fid,'%s\n',tcl{:}); % '%s\n'
fclose(fid);
Giving (note how all EOL are the Windows-style):
which is exactly the same as the input file, except for line 50.
Gifari Zulkarnaen
Gifari Zulkarnaen on 23 Feb 2020
Amazing, I understand now, thank you very much for your time answering and explaning, really appreciate it. Your last format works very well, except that I need to delete last cell element so that it doesn't create additional empty last line in each iteration. Thankyou2.
function gap = objective(A)
tcl = regexp(fileread('Truss2.tcl'), '\r?\n', 'split')'; % '\r?\n'
tcl{50} = sprintf('set A %g',A);
tcl(end) = [];
fid = fopen('Truss2.tcl','wt'); % must be text mode!
fprintf(fid,'%s\n',tcl{:}); % '%s\n'
fclose(fid);
!OpenSees.exe Truss2.tcl
clc
fid2 = fopen('example.out','r');
formatSpec = '%d %f';
sizeA = [1 Inf];
data = fscanf(fid2,formatSpec,sizeA);
fclose(fid2);
d = data(2);
gap = abs(d - 5);
end
Stephen Cobeldick
Stephen Cobeldick on 23 Feb 2020
"...except that I need to delete last cell element so that it doesn't create additional empty last line in each iteration"
This is due to a trailing newline in the file, which when the text is split by regex creates an empty cell at the end of the array, which is thus printed as another line of text... itself with a newline at the end! I don't recommend just removing the last cell, because if the file does not end with a newline, then you will delete the last line of the file without any warning.
A more robust solution would be to check if the last cell is empty before deleting it, or to remove trailing whitespace when you import the file string:
str = deblank(fileread('Truss2.tcl')); % remove trailing whitespace
tcl = regexp(str,...)

Sign in to comment.

More Answers (0)

Tags