Swift: Command-line basics

Just because someone wandered along today asking about input from stdin. No guarantees about edge conditions.

import Foundation
import Darwin

var myString : UnsafeMutablePointer<Int8> = UnsafeMutablePointer.alloc(100)
println("Enter your name")
fgets(myString, 100, stdin)
let myName = String.fromCString(myString)
println("Hi \(myName!)")

3 Comments

  • I don’t think `UnsafeMutablePointer` will free the memory when it goes out of scope. You’ll want to add something like

    myString.dealloc(100)

    at the end. Also, the `import Foundation` is unnecessary here.

  • FWIW, I made a new version that has a few benefits:

    1) it uses getline() instead of fgets() so it will allocate the buffer for you, ensuring it holds the entire line
    2) It handles input errors, including EOF
    3) It trims off the trailing newline


    import Darwin
    println("Enter your name")
    var input = UnsafeMutablePointer.null()
    var cap: UInt = 0
    errno = 0 // EOF doesn't set errno, so we need this to distinguish
    var len = getline(&input, &cap, stdin)
    if len == -1 {
    if errno == 0 {
    // EOF
    len = 0
    } else {
    "error".withCString() { perror($0) }
    exit(1)
    }
    } else {
    // trim off the trailing newline
    if UInt8(input[len-1]) == UInt8("n") {
    input[len-1] = 0
    }
    }
    let myName = String.fromCString(input)
    println("Hi (myName!)")
    // don't use .dealloc(), as we didn't use .alloc(), and we don't know what
    // allocator UnsafeMutablePointer uses internally.
    free(input)

  • I believe there’s a better solution for that:
    https://github.com/shoumikhin/StreamScanner