reading keyboard input from xcode playgroud


(Mr Bee) #1

Hi all,
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.
Here's the code:
import Foundation
func input() -> String { let keyboard = FileHandle.standardInput let inputData = keyboard.availableData let encoding = String.Encoding(rawValue: String.Encoding.utf8.rawValue) let strData = String(data: inputData, encoding: encoding) return strData! as String}
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() So, does anyone know how to make it works (again)? Thank you.
Regards,
–Mr Bee


(Zhao Xin) #2

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?

Here is my output in terminal:

$ swiftc main.swift

$ ./main

abc

Enter your name: You name is abc

$

As you can see, the program asked me to input my name before it showed the
notification. In playground, the situation is alike.

However, if the code is running as a command line tool, created by Xcode ->
Create a new project -> macOS, command line tool, everything works fine.

Zhaoxin

···

On Sun, Sep 18, 2016 at 9:16 PM, Mr Bee via swift-users < swift-users@swift.org> wrote:

Hi all,

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.

Here's the code:

import Foundation

func input() -> String {
  let keyboard = FileHandle.standardInput
  let inputData = keyboard.availableData
  let encoding = String.Encoding(rawValue: String.Encoding.utf8.rawValue)
  let strData = String(data: inputData, encoding: encoding)
  return strData! as String
}

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()

So, does anyone know how to make it works (again)? Thank you.

Regards,

–Mr Bee

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


(Mr Bee) #3

I knew it's a bug, hence this email.
I need input() function to accept user input from within Playground, not from Terminal (command line). I want it on Terminal, I would have used the readLine() function which ser
–Mr Bee

Pada Selasa, 20 September 2016 21:13, Zhao Xin <owenzx@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?
Here is my output in terminal:
$ swiftc main.swift $ ./main abcEnter your name: You name is abc$
As you can see, the program asked me to input my name before it showed the notification. In playground, the situation is alike.
However, if the code is running as a command line tool, created by Xcode -> Create a new project -> macOS, command line tool, everything works fine.
Zhaoxin

···

On Sun, Sep 18, 2016 at 9:16 PM, Mr Bee via swift-users <swift-users@swift.org> wrote:

Hi all,
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.
Here's the code:
import Foundation
func input() -> String { let keyboard = FileHandle.standardInput let inputData = keyboard.availableData let encoding = String.Encoding(rawValue: String.Encoding.utf8.rawValue) let strData = String(data: inputData, encoding: encoding) return strData! as String}
func write(_ txt: String) { print(txt, terminator: "")}
func read() -> String { let c = CharacterSet.whitespacesAndNew lines return input().trimmingCharacters(in: c)}

/* main program */

write("Enter your name: ")let s = read() So, does anyone know how to make it works (again)? Thank you.
Regards,
–Mr Bee

______________________________ _________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/ mailman/listinfo/swift-users


(Jeremy Pereira) #4

I knew it's a bug, hence this email.

Pada Selasa, 20 September 2016 21:13, Zhao Xin <owenzx@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.

···

On 20 Sep 2016, at 17:54, Mr Bee via swift-users <swift-users@swift.org> wrote:

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