Diary does not print backspace ('\b') properly - alternative/solution?

63 views (last 30 days)
I have a bunch of scripts + functions that output their progress to the command window. At the same time I would like to write the same information to some kind of log file. diary normally does the job well in such a situation. However, I am printing a number of counters that make use of backspace characters. When I check my diary log afterwards, it turns out that every single counter output, as well as some weird characters are printed to my log file...
Is there any way to fix this behavior? And if not, is there any alternative? Using fprintf to print a file is not really an option, as I also want to print to the command window. Additionally, I would have to pass FID along many functions.

Answers (3)

Walter Roberson
Walter Roberson on 4 Sep 2015
fprintf() with no fid writes to the command window, as does fprintf(1). fprintf(2) also writes to the command window but might be formatted specially as it is reserved for error messages.
Could you say more about the "weird characters" ? Have you checked to see which ASCII or Unicode positions they occupy?
  3 Comments
Walter Roberson
Walter Roberson on 4 Sep 2015
Log files show everything written to them. If you emit a backspace to the log then it is going to record it. Log files don't know what is important. If you had a "cls" would you want the log file to go back and erase everything it had logged so far, since that is what the screen would look like?
You have 3 options:
  1. Don't count to output like that, switch to waitbar()
  2. Create your own log file and don't write the intermediate counter values to it; or
  3. post-process the log file.
For example if you were using OS-X or Linux, you could just run the output through col -b
In any editor that permits search and replace with meta characters, you can tell it to replace "anything" followed by backspace, with nothingness, and do that repeatedly. For example in age old vi this would be:
1,$s/.^H//g
where the ^H would be entered by pressing control-V and the backspace. Though you might have to repeat this command up to the maximum number of consecutive backspaces you have.
Niels
Niels on 4 Sep 2015
You've got a very valid point there. I think a combination of option 1 and 2 will be probably be the best solution for me. I was hoping for a less time consuming option, but I guess I'll simply have to go for a different approach if I don't want to pollute my log file with intermediate counter values :)

Sign in to comment.


Cedric
Cedric on 4 Sep 2015
Edited: Cedric on 4 Sep 2015
I suspect that it does save the backslash character correctly, but that the editor that you are using to open the diary doesn't interpret it correctly or that you don't understand the code that the editor displays.
\b is a special character ( ASCII code 8 ); it is not meant to be displayed (same as others like \t\r\n). Instead, it tells whatever processes/displays the content to do something (e.g. go to a new line for \n, etc). If you open the diary file with Notepad++, for example, it will display a special BS symbol to indicate that there is a \b. If you open it with MATLAB editor, MATLAB displays a square that is not very explicit.
You can experiment with this. Open a diary in a new folder (so you have a fresh diary), print something with a backspace, and close the diary:
>> diary on
>> fprintf( 'AB\bC\n' ) ;
AC
>> diary off
Here you see that we inserted a \b after the B, so it is not display, and we get AC and a new line as output.
Now we can load the diary as characters, and DISP it:
>> content = fileread( 'diary' ) ;
>> content
content =
fprintf( 'AB\bC\n' ) ;
AC
diary off
So is it just the text that you saw, or does it contain the special characters (interpreted/displayed correctly here)? If you opened the diary in an editor, you know that it contains the special characters, but let's observe them. One way to display ASCII codes is to typecast to double by adding 0 to the char variable content:
>> content + 0
ans =
Columns 1 through 19
102 112 114 105 110 116 102 40 32 39 65 66 92 98 67 92 110 39 32
Columns 20 through 38
41 32 59 13 10 65 66 8 67 13 10 100 105 97 114 121 32 111 102
Columns 39 through 41
102 13 10
If you look at an ASCII table, you see that characters 'A','B','C' correspond to ASCII codes 65, 66, 67, that you see in columns 25, 26, and ... 28, because the 27th ASCII code is the ASCII code of the backspace: 8.
Why are you using a backslash by the way? This is not something that is done very often nowadays. Did you do something like:
fprintf( '000') ; for k = 1 : 10, fprintf( '\b\b\b%03d', k ) ; pause(1) ; end, fprintf('\n') ;
Depending what you want to achieve, you can load the diary and process it's content to account for backspaces, but I predict that it is not going to be a very clean and stable approach.
  1 Comment
Niels
Niels on 4 Sep 2015
Thanks for your response. I just commented Walter's response before seeing yours, but it's exactly as you stated.
Indeed, notepad++ shows a BS sign; loading it back into matlab makes it function as it should. But text files / dat files both do not like the backspace character.
You're also right on how I use it. I intend to use it as a simple counter, but the log file should only show that the counter has completed successfully, which it does not do correctly at this moment.

Sign in to comment.


Alejandro Estay
Alejandro Estay on 4 Jul 2019
the proper behavior is to make text cursor go back one space, without writing nothing. Matlab behavior ins not correct because it writes the symbol, but not perfom any action.

Categories

Find more on Entering Commands in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!