Swift OS X字符串到Int转换错误

时间:2016-03-25 03:57:14

标签: string swift macos int unwrap

我在Swift OS X Xcode项目中将String转换为Int时遇到问题。我有一些数据以逗号分隔格式保存在文本文件中。文本文件的内容如下:

  

1,赛斯纳172,3,54.4,124,38.6112

(以及最后的换行符)

我读取文本文件并将其分开,首先由\n单独获取每一行,然后由,单独获取每个元素。执行此操作的代码如下:

    if let dir : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
        let path = dir.stringByAppendingPathComponent("FSPassengers/aircraft.txt")

        do {
            let content = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)

            if content != "" {
                let astrContent:[String] = content.componentsSeparatedByString("\n")
                for aeroplane in astrContent {
                    let aSeperated:[String] = aeroplane.componentsSeparatedByString(",")

                    print(aSeperated[0])
                    print(Int(aSeperated[0]))

                    //self.aAircraft.append(Aircraft(id: aSeperated[0], type: aSeperated[1], passengerCapacity: Int(aSeperated[2])!, cargoCapacityKg: Double(aSeperated[3])!, cruiseSpeed: Int(aSeperated[4])!, fuelLitresPerHour: Double(aSeperated[5])!))
                }
            }
        }
        catch {
            print("Error")
        }
    }

这里的最终结果是将每条记录(文本文件的每一行)分配到数组aAircraft中。此数组由名为Aircraft的自定义对象组成。自定义类如下:

class Aircraft: NSObject {
var id:Int = Int()
var type:String = String()
var passengerCapacity:Int = Int()
var cargoCapacityKg:Double = Double()
var cruiseSpeed:Int = Int()
var fuelLitresPerHour:Double = Double()

override init() {}
init(id:Int, type:String, passengerCapacity:Int, cargoCapacityKg:Double, cruiseSpeed:Int, fuelLitresPerHour:Double) {
    self.id = id
    self.type = type
    self.passengerCapacity = passengerCapacity
    self.cargoCapacityKg = cargoCapacityKg
    self.cruiseSpeed = cruiseSpeed
    self.fuelLitresPerHour = fuelLitresPerHour
}

}

在上面的第一个代码提取中,我分割文本文件内容并尝试将它们分配到数组中,您将看到我已注释掉append行。我这样做是为了让应用程序编译,目前它给我带来了错误。

错误围绕根据需要将String值转换为Int和Double值。例如,Aircraft.idaSeperated[0]需要是Int。您可以看到我使用行Int(aSeperated[0])将String转换为Int,以便将其分配给自定义对象。但是,这行代码失败了。

第一个代码提取中的两个print语句输出以下值:

  

1
  可选(1)

如果我在第二个print语句的末尾添加!来制作它们:

print(aSeperated[0])
print(Int(aSeperated[0])!)

我得到以下输出:

Error Screenshot

我理解错误意味着什么,它试图打开一个可选值,因为我强制解包它,它无法在我传递给它的字符串中找到一个Int值,但我不明白为什么我是得到错误。字符串值为1,非常明显是整数。我做错了什么?

2 个答案:

答案 0 :(得分:0)

因为Casena 172无法转换为Int。您还有其他十进制数,在将它们转换为Int时,您将失去精确度。使用NSScanner从CSV字符串创建初始值设定项:

init(csvString: String) {
    let scanner = NSScanner(string: csvString)
    var type: NSString?

    scanner.scanInteger(&self.id)
    scanner.scanLocation += 1
    scanner.scanUpToString(",", intoString: &type)
    self.type = type as! String
    scanner.scanLocation += 1
    scanner.scanInteger(&self.passengerCapacity)
    scanner.scanLocation += 1
    scanner.scanDouble(&self.cargoCapacityKg)
    scanner.scanLocation += 1
    scanner.scanInteger(&self.cruiseSpeed)
    scanner.scanLocation += 1
    scanner.scanDouble(&self.fuelLitresPerHour)
}

用法:

let aircraft = Aircraft(csvString: "1,Cessna 172,3,54.4,124,38.6112")

答案 1 :(得分:0)

正如@mrkxbt所提到的,该问题与文本文件中数据之后的空行有关。字符串被分割为\n,它将两个值分配给数组。第一个值是包含数据的字符串,第二个值是空字符串,所以显然第二组拆分(由,)失败。修改后的工作代码如下:

    if let dir : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
        let path = dir.stringByAppendingPathComponent("FSPassengers/aircraft.txt")

        do {
            let content = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)

            if content != "" {
                let astrContent:[String] = content.componentsSeparatedByString("\n")
                for aeroplane in astrContent {
                    if aeroplane != "" {
                        let aSeperated:[String] = aeroplane.componentsSeparatedByString(",")

                        print(aSeperated[0])
                        print(Int(aSeperated[0])!)

                        self.aAircraft.append(Aircraft(id: Int(aSeperated[0])!, type: aSeperated[1], passengerCapacity: Int(aSeperated[2])!, cargoCapacityKg: Double(aSeperated[3])!, cruiseSpeed: Int(aSeperated[4])!, fuelLitresPerHour: Double(aSeperated[5])!))
                    }
                }
            }
        }
        catch {
            print("Error")
        }
    }