Fprintf: how to automatically move to a new line when reach end of screen?

20 ビュー (過去 30 日間)
Xh Du
Xh Du 2017 年 7 月 7 日
回答済み: Jan 2017 年 9 月 17 日
Hi all,
I have something like this:
clear; clc;
for i = 1:100
fprintf('%d', i)
end
Here I use fprintf to indicate the progress of the loop. For the 100 iterations, the printed number easily reach the edge of screen and cursor moves with the increasing number in one line only. Is there a way to make fprintf automatically change to a new line when reach the edge of screen?
Many thanks!

回答 (5 件)

Guillaume
Guillaume 2017 年 7 月 7 日
It's not possible. You would need access to information about the width of the command window, something matlab does not provide.
Providing progress information through the command window is ok when developing but should be avoided for the finished product. (I hate it. Don't pollute my command window!) You would be much better off using a progress bar:
hbar = waitbar(0, 'About to start');
steps = 100;
for step = 1:steps
waitbar(step/steps, hbar, sprintf('%g%%done', step/steps*100));
pause(.1);
end
close(hbar);

Stephen23
Stephen23 2017 年 7 月 7 日
There is no automatic way to do this, but on MATLAB versions before R2014b it was possible to get the command window width:
N = get(0,'CommandWindowSize');
which you can then use to count the characters and add a newline when required.
  4 件のコメント
Guillaume
Guillaume 2017 年 7 月 7 日
It breaks since you can't adjust what is already printed.
Stephen23
Stephen23 2017 年 7 月 14 日
@Guillaume: I am totally confused. Who said anything about adjusting "already printed" text? Certainly not in Xh Du's question, nor in my algorithm description is there any mention of "already printed" text.
The algorithm does not adjust text that is "already printed": it works by printing only the number of required characters on each line, no "adjustment" afterwards is needed. Once printed each line stays exactly as printed, just like it should.
Did you make your claim that it "will break" based on your own extra, implicit requirement that is not part of that original question and not listed as a feature of that algorithm, that all existing text should reflow? I would be quite surprised if all users wanted and expected that behavior: I for one am quite happy without text reflow (although it would be nice as an option).

サインインしてコメントする。


Jan
Jan 2017 年 7 月 7 日
It does not only depend on the size of the command window, but on the font also. It matters if it is a fixed-width or proportial font, if the 1 is smaller than the 0.
Using the text field of the command window for a layout trick like the determination of the right limit is indirect and clumsy. Use the text output for text output, and GUI elements for displaying the progress. Guillaume's suggestion of the progressbar is fine.
You could display the progress in the Command Window also without disturbing the test output using FEX: CmdWinTool:
for k = 1:100
pause(0.1);
CmdWinTool('statusText', sprintf('Progress: %d of %d', k, 100));
end

Jan
Jan 2017 年 9 月 17 日
Perhaps this helps:
Extent = matlab.desktop.commandwindow.size
or the undocumented (in R2016b)
rows = builtin('_getcmdwinrows')
cols = builtin('_getcmdwincols')

Image Analyst
Image Analyst 2017 年 7 月 7 日
I don't know why the right hand side of the screen is so important. If you just want to break it after some arbitrary number of elements have been printed, then use mod:
for i = 1:1000
fprintf('%d ', i)
if mod(i,20) == 0
fprintf('\n'); % New line every 20 numbers.
end
end
  3 件のコメント
Stephen23
Stephen23 2017 年 7 月 7 日
編集済み: Stephen23 2017 年 7 月 7 日
"I don't know why the right hand side of the screen is so important"
I am clearly delusional for believing that computers can be designed to serve their users' needs, rather than the user being forced to follow restrictions that are not even technically required. Surely computers are intelligent enough these days that they can handle the task of measuring, aligning, and flowing text? Or is this such a complex task that the boffins at Google haven't yet figured it out?
Image Analyst
Image Analyst 2017 年 7 月 7 日
I wouldn't even do what Xh did. I'd do
fprintf('%d\n', k) % new k on each line.
and then I doubt it's just the poorly-named "i" that is wanted, he probably wants to know other things too, so I'd put other variables I was interested in into the fprintf() also.
If I did want multiple i on one line (which I don't usually), I think I'd put a known, round number of elements on each line, and have them formatted to all the same field size. That way you can count rows and know how many got printed, like, for 10 numbers per line, 2 rows = 20, 10 rows = 100, etc. If the field width changes, and the command window width changed, you never know how many numbers might get printed to each line, or in total. For example, 15 lines could be 130, 150, 180, or any other number of items. So, I'd do, for example:
for k = 1:90
someVariable = k*rand; % Something else you want to see.
fprintf('(%2d, %4.1f), ', k, someVariable)
if mod(k, 10) == 0
fprintf('\n'); % New line every 10 number pairs.
end
end
Now we get 10 pairs of items on each line and everything is nicely numbered/countable and lined up nicely. I don't know why an unknown, variable number of numbers on each line would be preferable to this nicely ordered layout.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeEnvironment and Settings についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by