Search code examples
stringswitch-statementswiftnsfilehandle

Why can't this switch statement make any matches against input from the console?


In order to get more familiar with Swift I put together the start of a class designed to represent the needs and wants of a human game character. Right now it keeps track of a water and food variable. These variables are changed by functions that accept NSStrings (or Strings, I have tried both) and run that parameter through a switch statement.

import Foundation

class human {

var food:Int = 0
var water:Int = 0

func setFood(str:NSString) {
    var generic:String = "The \(str) filled your Food Hole with "

    switch str {
    case "chicken":
        food += 10
        println(generic + "10 points.")
    case "bread":
        food += 5
        println(generic + "5 points")
    case "beans":
        food += 10
        println(generic + "10 points")
    default:
        if food < 30 {
            food += 2
            println("That wasn't really food...Here's two pity points")

        } else {
            println("Stop eating garbage")
        }
    }
}

func setWater(str:NSString) {
    var generic:String = "The \(str) filled your Water Hole with "

    switch str {
    case "water":
        water += 30
        println(generic + "30 points.")
    case "mud water":
        water += 10
        println(generic + "10 points. And you're gross.")
    case "radioactive coolant":
        water += 5
        println("Okay so that technically worked but wasn't a good idea")
    default:
        println("Don't put that in your mouth")
    }
}
}

Here is the code for getting input from the console:

var hu = human()

hu.setFood("bread")
println(hu.food)    //this works fine

let keyboard = NSFileHandle.fileHandleWithStandardInput()

while (keyboard) {
println("What do you eat or drink?")

var input = NSString(data: keyboard.availableData, encoding: NSUTF8StringEncoding)
hu.setFood(input)

println(input) //check input to confirm it even holds a string
}

The first setFood function with the hardcoded string works fine. The correct case is matched, the variable is updated correctly, the text prints, etc. I have a println statement at the end there so that I can see what the input variable actually holds and it does seem to hold some kind of String.

The specific problem is that the switch statement always selects the default case when matching against input from the console. Inputting a valid string like chicken into the console will not match the chicken case of the switch statement.

Is this an encoding issue? I've tried NSString, String, I've tried casting input to a String, using a lowercase method to see if that "cleans" things up. I've looked through the library reference in Xcode for anything that might give me what I want without any luck. I am a beginner at Swift obviously and I've never written any Objective-C. I hope I'm not missing something obvious. Thanks.


Solution

  • The console input includes the newline that was inserted by pressing "enter". If you change the last println(input) to println("<\(input)>") you will see it prints

    <chicken
    >
    

    One quick solution is to add

    input = input.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    

    before passing it to setFood()