Write data to text file containing \s in string?

Hi,
I'm writing a code that change some data for some lines in a text file. However, a line that is not changed (only taken from first file and written to the second text file) contains some backslashes (search path). I get a warning about this and the text sting containing this path is not fully written. I can not solve this. Can someone help me?
Warning: Control Character '\s' is not valid. See 'doc sprintf' for
control characters valid in the format string.
CODE:
textfil = fopen('C:\Stltmp2D\Dat\TEMP.dat', 'r');
textfil2 = fopen('C:\Stltmp2D\Dat\TEMP_UT.dat', 'w');
%
tline = fgetl(textfil);
%
k =1;
while ischar(tline)
if strcmp(tline(1:2),'LX');
tline(15:20) = num2str(Lx(1),'%4.4f');
tline(25:30) = num2str(Lx(2),'%4.4f');
tline(35:40) = num2str(Lx(3),'%4.4f');
end
fprintf(textfil2,tline);
fprintf(textfil2,'\n'); %%????
tline = fgetl(textfil);
k = k+1;
end % END OF CODE
Best regards
Christopher

 Accepted Answer

Change your two fprintf to just this one line:
fprintf(textfil2, '%s\n', tline);

9 Comments

This works! Thank you Guillaume!
I still have a problem. My code do not change row after every while-iteration. I had this problem with the old code too. I have had It working with row change earlier but I do not remember that I have made any changes... Strange. BR Chris
Open the files using text mode:
textfil2 = fopen('C:\Stltmp2D\Dat\TEMP_UT.dat', 'wt');
^ you need this!
It works. Thank you Mr. Cobeldick!
BR Chris
Jan
Jan on 2 Mar 2018
Edited: Jan on 2 Mar 2018
The 'wt' flag converts the linebreak '\n' to the DOS linebreak '\r\n'. Is this really useful here? As far as I understand the problem is to write the characters '\' and 'n', not the control character char(10) , alias sprintf('\n') .
The problem was to write '\' . The solution works. The text file name has the end'.dat'.
@Christopher,
You must have been using a very basic text editor, such as notepad, for you to say "My code do not change row after every while-iteration" Most modern text editors would have shown the text file on multiple lines.
There are two main conventions for marking the end of a line in a text file. The Windows convention is to have a carriage return followed by a linefeed ( char([13 10]) or '\r\n') while the unix convention is just a linefeed ( char(10) or '\n'). Most text editors on Windows apart from notepad work with either convention. Hence why Jan asks if it is really useful there. Use any text editor other than notepad and you'll never see a problem. I personally use notepad++
What the 't' flag in fopen tells matlab to do is to discard the '\r' if present when reading a text file and append it when writing if not present, iif the current platform is windows.
Why so much hate here for the text option?
While notepad is clearly close to useless for real work the reality is that it is also commonly used by beginners, and using the text option costs almost nothing in typing or runtime. It is not clear why you all hate it so much, because so far no one has actually given a reason why using it is so incredibly bad. As far as I can tell using it for all text files would allow the user to write code that works simply regardless of the source of their input text, and would write files that actually work for them (yes, because they might even be using notepad, or giving it to their boss who uses notepad and knows no different...).
This problem is not just related to writing files but also reading them: how would you suggest writing a tool for parsing files from both *unix and MS? I have written several large file-parsing tools using regular expressions and that had to work with files from any OS: this simply would have been a nightmare if I had had to account for every newline combination, but by simply using the text option it let me write the regular expressions using \n which was much clearer and it worked, regardless of what files I gave it. What serious alternative would anyone suggest?
Why so much hate for this option? It lets the users concentrate on what they actually want to be working on, which is surely the point.
I have no hate at all for the text option. In fact, I always use it in my code if I deal with text files.
I was explaining Jan's viewpoint that it is not particularly necessary as most tools don't really care which convention you use for line endings.
Indeed, the option is critical for reading text files. For writing, not so much.
In fact, I've got an enhancement request I filed a while ago to Mathworks, to improve the fileread function so that it uses the 'rt' option. As it is, it needlessly complicates the 'lineanchor' option of regexes since you have to account for a possible '\r' before the anchor.
@Stephen: I "hate" the text mode, because it confuses beginners and is only useful to support the ancient Notepad editor. Any other editor handles \n and \r\n linebreaks perfectly and transparently.
I older Matlab versions, the control characters have been interpreted differently, e.g. \b and ^Z. Therefore the the text mode caused incompatible behavior between Matlab versions, which is a serious problem for my needs.
I'm using an enhanced version of fileread, which replaces all \r\n by \n at first, then all remaining \r by \n also (old MacOS style before MacOS-X). This needs just two strrep calls and is not a nightmare.
I have to write code, which creates the same results under Windows and Linux. Having exactly the same output allows for an easier comparison of the output of automated tests, because comparing the checksum of the files is sufficient already. When any software use only \n as linebreaks, I would not have to test 3rd party software, if it fails at unexpected linebreaks (as e.g. Matlab 6.1 did under Linux).
Therefore the text mode is an ancient method to support one outdated editor, while the \n as line break should have been the standard since 1976 already.

Sign in to comment.

More Answers (1)

Jan
Jan on 2 Mar 2018
Edited: Jan on 2 Mar 2018
Replace
fprintf(textfil2, '\n')
by
fprintf(textfil2, '%s', '\n')
In the first case '\n' is interpreted as format specifier, while in the second case '%s' means to insert the argument as string. Alternatively:
fwrite(textfil2, '\n', 'char')
This does not interpret anything, but writes the string directly into the file.
The same problem occurs in error messages, which contain file names:
FileName = 'C:\valid\folder\%23xyz';
error('My:Error:ID', ['File access failed: ', FileName]); % FAIL
Better:
error('My:Error:ID', 'File access failed: %s', FileName);

3 Comments

Great! Now I understand. Thanks
No!
fprintf(textfil2, '\n')
is interpreted correctly by matlab and will output char(10) to the file. It is not interpreted by matlab as a format string as it does not contain any format specifier (which require a %). Doing
fprintf(textfil2, '%s', '\n')
will actually output the literal string '\n' to the file, not char(10). Escape sequences are not interpreted in the inputs to the format string.
The problem was with the other line
fprintf(textfil2, tline)
As stated in the question tline could contain \, which if present in the second input argument are interpreted as escape character (just as it is for the '\n'). Fixing the actual problem only required:
fprintf(textfil2, '%s', tline);
fprintf(textfil2, '\n'); %didn' need to change
In my answer I just conflated the two lines
@Guillaume: As far as I understood, the OP wants the characters '\' and 'n' appear in the file:
However, a line that is not changed (only taken from first file
and written to the second text file) contains some backslashes
(search path).
The actual warning is:
Control Character '\s' is not valid.
So it is a problem of writing the backslash to the file and therefore the text mode is not relevant here.
You wrote:
The problem was with the other line
fprintf(textfil2, tline)
Yes, exactly. And this tline contains backslashes.
But my example might be confusing. All I wanted to emphasize is the difference between
fprintf(fid, '\n')
and
fprintf(fid, '%s', '\n')

Sign in to comment.

Categories

Products

Community Treasure Hunt

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

Start Hunting!