[swift-users] Bls: reading keyboard input from xcode playgroud

Jeremy Pereira jeremy.j.pereira at googlemail.com
Wed Sep 21 08:42:25 CDT 2016


> On 20 Sep 2016, at 17:54, Mr Bee via swift-users <swift-users at swift.org> wrote:
> 
> I knew it's a bug, hence this email.
> 
> 
> Pada Selasa, 20 September 2016 21:13, Zhao Xin <owenzx at gmail.com> menulis:
> 
> 
> I test you code in command line `swiftc main.swift` and in macOS Command Line Tool app.
> 
> Here is the main.swift:
> 
> import Foundation
> 
> import Foundation
> 
> func input() -> String {
>     let keyboard  = FileHandle.standardInput
>     let inputData = keyboard.availableData
>     let strData   = String(data: inputData, encoding: .utf8)
>     return strData!
> }
> 
> func write(_ txt: String) {
>     print(txt, terminator: "")
> }
> 
> func read() -> String {
>     let c = CharacterSet.whitespacesAndNewlines
>     return input().trimmingCharacters(in: c)
> }
> 
> /* main program */
> 
> write("Enter your name: ")
> let s = read()
> print("You name is \(s)")
> 
> It turns out that the input request was ran before the `write("Enter your name: ")`. I don't why. Maybe it is a bug?

For what it’s worth, this is not a bug, it’s an artefact of the way character IO works. stdio streams are either buffered, unbuffered or line buffered. The stdout stream is line buffered so the output “Enter your name:” sits in a buffer waiting for a line feed which doesn’t happen until the end of the print statement.

You can force stdout to flush itself with the c library call fflush(), i.e.

func write(_ txt: String) {
    print(txt, terminator: "")
    fflush(__stdoutp)
}

The reason why it works OK in the Xcode console must be because stdout is directed to a pipe instead of a terminal.I suspect the combination of this and how the pipe is read from the other end is what makes it work correctly.


> 
> Another question. I used to use this snippet to read keyboard input from XCode's Playground. And it used to work very well. Today, I just updated my XCode to v.8 and Swift v.3. After a little bit modification here and there due to Swift 3 incompatibility, I got this code compiled without error. But it doesn't work. No keyboard input is taken. It just stucks.

It hasn’t got stuck, put a print statement at the end and you’ll see it gets executed. The problem is that FileHandle.availableData returns immediately with empty data. According to the documentation this means that standard input has been closed. But it could also be the case that it is set to non blocking.

> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users



More information about the swift-users mailing list