Sometimes the most obscure problems have simple solutions.
A few days ago, a Matlab user asked whether it is possible to solve the flashing effect whenever he cleared the Command Window. It turns out that this user runs a long process, and wanted to display interim information (progress etc.) in the Command Window. The obvious solution that he employed was to display the data in the Command Window, and then erase the window (using clc) and rewrite the data periodically.
Using control characters
Now, there are obviously other ways of doing this, the most obvious being a dedicated GUI window that displays the information and updates periodically. But to solve the user’s immediate issue, the solution I provided (acting on the 80-20 Pareto principle – a dedicated GUI window is better but would take longer to set up) was to use control characters to erase old data when displaying new data, rather than clearing the window. Here is the basic pseudo-code that I suggested (slightly modified):
reverseStr = ''; for idx = 1 : someLargeNumber % Do some computation here... % Display the progress percentDone = 100 * idx / someLargeNumber; msg = sprintf('Percent done: %3.1f', percentDone) fprintf([reverseStr, msg]); reverseStr = repmat(sprintf('\b'), 1, length(msg)); end |
The idea is to use the backspace control-character (BS, or sprintf(‘\b’), or char(8)) repeatedly in order to erase the preceding characters from the Command Window, then print the new data.
(see related comments by Helge here)
Compatibility aspects
Back in the good-ol’-days, when I was hacking away c-shell scripts, ages ago when I created command-prompt C apps, and aeons ago on Vax (R.I.P.), I would have used the carriage-return control-char (CR, or sprintf(‘\r’), or char(13)) to completely erase everything up to the beginning of the current line. This would be much simpler than the repeated backspaces (using repmat in the pseudo-code above). Unfortunately, CRs behave differently in Matlab’s Command Window, causing \r to jump to the next line (similarly to \n), rather than erase to the beginning of the line. This is probably due to Java’s JTextArea’s implementation (on which the Command Window is based), and not due to Matlab itself. In any case, it shows that not all control characters behave the same way on different environments, which is actually not very surprising.
Another widely-used control character, the bell control-char (BEL, or sprintf(‘\g’), or char(7)) is not accepted at all by Matlab’s implementation of sprintf and its variants. Matlab users can always use the beep function of course, I’m just pointing this out as another inconsistency between Matlab’s *printf() implementation and that of other environments. And don’t even think of using raw device escape sequences (ah, the good-ol’-days, long gone now…).
Control characters that are accepted in Matlab and behave as expected include: FF (\f), NL (\n) and TAB (\t). These can be used in fprintf to modify the text spacing. The sprintf documentation mentions which of the control characters are accepted, so this is not, strictly speaking, an undocumented aspect. However, note that there is a discrepancy between the list of accepted control chars in the online/doc page compared to the help section (\a and \v are mentioned in the former but not in the latter).
For another type of Command Window text manipulation, namely colors, refer to my cprintf utility. For anyone who hasn’t noticed, I recently updated the utility on the Matlab File Exchange. Due to some internal modifications by MathWorks to the Command Window implementation in R2011b, cprintf no longer needs to pad color segments with spaces, and separate color segments can now be directly adjacent to each other (in R2011a and earlier, the spaces are unfortunately needed).
Have you used control characters in an innovative manner in your work? If so, please share your experience in a comment.
Happy New Year everyone!
The Vax certianly is a blast from the past! But I would guess that very few readers of this blog know what the related acronym DEC stood for or have experience entering a boot loader into a PDP8 via the toggle switches on the front panel.
See, for example, class “ConsoleProgressBar” http://www.mathworks.com/matlabcentral/fileexchange/30297-consoleprogressbar
I used char(0) to clear the ‘CurrentCharacter’ property, checked IF 13==get(gcf,’currentcharacter’) … to detect whether the user has pressed the [RETURN] key, and did similar stuff also to check special keyboard input, e.g., TAB=char(9) or any left/right/up/downarrow char(28:31) etc. Not all of this is “innovative”, but clearing the ‘CurrentCharacter’ property is not as trivial as it seems… in fact, this property cannot be set to an empty value (R13-2007b):
The following, however, works:
Apparently, the ‘CurrentCharacter’ property can -in principle- be used to get/set virtually any char(0…255), incl. those for which no keys exist on the keyboard. However, I cannot exclude unexpected effects under different Matlab versions and OSs.
Is it possible to display the result being displayed in a command window onto a static text box in GUI??
[…] carriage return (or ‘r’) escape sequence which in Windows is the same as a newline (read here). So, I implemented a customized ProgressMonitor class for Matlab that uses backspace (or […]
I use ‘dispstat’ function just for this purpose. It can update the previous output which is a missing function of default ‘disp’. Very simple to use. It can be downloaded from here:
http://www.mathworks.com/matlabcentral/fileexchange/44673
***Sample usage:
***Output:
@Kasim – it would have been nice if you included a reference to this webpage in your utility’s description. After all, it’s based on the content of this webpage (specifically, the \b trick). It is not very polite to use someone’s work without acknowledging it; to then go back to that source and post a link to your work only increases the apparent impoliteness…
The utility itself does indeed seem useful.