Input from the keyboard in command line application
I managed to figure it out without dropping down in to C:
My solution is as follows:
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)!
}
More recent versions of Xcode need an explicit typecast (works in Xcode 6.4):
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)! as String
}
Swift's readLine() is nil when I enter a long string in STDIN
readLine()
is a wrapper around the stdio getline
function, and that function requires
only that a newline character occurs within the first SSIZE_MAX
characters of the input. On the 64-bit OS X platform, SSIZE_MAX
is 2^63 - 1
which means that this is only a theoretical limitation.
So readLine()
is not the problem, it can read arbitrarily long lines as long as they fit into your computers memory.
But it seems that you can not paste more than 1023 characters into the
Xcode debugger console. (Edit: This was also observed at Read a very long console input in C++).
Running the program in a Terminal with input redirection from a file is one option to solve the problem:
$ ./myProgram < /path/to/inputData.txt
Another option is to add
freopen("/path/to/your/inputData.txt", "r", stdin)
at the beginning of the Swift program. This redirects the standard
input to read from the given file.
The advantage of this method is that you can still debug your program
in Xcode.
Swift: How to read standard output in a child process without waiting for process to finish
You are reading synchronously on the main thread, therefore the UI is not updated until the function returns to the main loop.
There are (at least) two possible approaches to solve the problem:
- Do the reading from the pipe on a background thread (e.g. by dispatching it to a background queue – but don't forget
to dispatch the UI updates to the main thread again). - Use notifications to read asynchronously from the pipe (see
Real time NSTask output to NSTextView with Swift for an example).
Related Topics
How to Implement iOServicematchingcallback in Swift
Swift 3 String Contains Exact Sentence/Word
Swift Covariant Generic Function:Placeholder Type Is a Subclass of Another
Fblpromises Framework Not Found
How to Disable a Constraint Programmatically
How to Get Coreml in Pure Playground Files
Programatic Constraints Not Obeyed
iOS 11 Large Title Navigation Bar Snaps Instead of Smooth Transition
How to Build a Swift Package for iOS Over Command Line
Use Multiple Codingkeys for a Single Property
How to Generate Random Numbers Without Repetition in Swift
How to Speed Up Updating Relationship Among Tables, After One or Both Tables Are Already Saved
Getting a Let Value Outside a Function
Swift Enum Raw Value: Not Working with Cgfloat = -1.0