2

I created a command line tool which does some long actions, and I want to notify the user through print statements, like:

"10% Done"
"20% Done"

on what percentage of the operation is done. If I use println, each progress will be printed into a new line (obviously), but is there a way in swift, that I can replace the last printed text with a new one, so on the console you can read only the actual percentage, not the actual and the ones that printed before?

Dániel Nagy
  • 11,815
  • 9
  • 50
  • 58

3 Answers3

10

If the output goes to the Terminal then you can use the fact that \r (Carriage Return) moves the "cursor" to the start of the current line, without advancing to the next line:

print("10% done ", terminator: "\r")
print("20% done ", terminator: "\r")
print("100% done")

(But note that this does not work in the Xcode debugger console.)

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks, I tried carriage return, but I thought it doesn't work because of the debugger concole, but works perfect in the terminal. – Dániel Nagy Mar 03 '15 at 13:16
  • At least as of Swift 5.5 you also need to add the terminator: "" parameter to print when doing this – Andreas Bergström Sep 19 '21 at 08:54
  • @AndreasBergström: You are completely right. I don't remember how it was in 2015, but that wouldn't have worked for a long time now. Thanks for the notice, I have updated the code. – Martin R Sep 19 '21 at 09:00
  • @martin-r: actually putting the \r in the string and just passing an empty string to terminator worked, I guess it otherwise appends a \n and print() did not work that way in its first versions? – Andreas Bergström Sep 19 '21 at 14:09
  • 1
    @AndreasBergström: Yes, without an explicit terminator a newline character is appended. There should be no difference between `print("...", terminator: "\r")` and `print("...\r", terminator: "")` but I prefer the former (the CR character *is* the terminator). – Martin R Sep 19 '21 at 14:11
8

Something like this works on the terminal console:

import Foundation
for i in 1...10 {
    print("\(i) \r", terminator: "")
    fflush(stdout)
    sleep(1)
}
pushkarnk
  • 323
  • 3
  • 10
0

No it's not possible. Swift can't access already printed out strings. But you could create a progressbar where you show the progress. For example like that:

|=========               | 40%

But you can't change the output of the log, after you've printed it out.

Christian
  • 22,585
  • 9
  • 80
  • 106
  • > But you can't change the output of the log, after you've printed it out. You can do this, as was shown by others – Luis Jul 23 '23 at 20:05