Swift OS X Строка в Int Ошибка преобразования

У меня проблемы с преобразованием строки в Int в моем проекте Swift OS X Xcode. У меня есть некоторые данные, сохраненные в текстовом файле в формате с разделителями-запятыми. Содержание текстового файла ниже:

1, Cessna 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.id, или же aSeperated[0] должен быть Int. Вы можете видеть, что я использую линию Int(aSeperated[0]) преобразовать строку в Int, чтобы назначить ее в пользовательский объект. Однако эта строка кода не работает.

Два оператора печати в первом фрагменте кода выдают следующие значения:

1
Дополнительно (1)

Если я добавлю ! до конца второго оператора печати, чтобы сделать их:

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

Я получаю следующий вывод:

Скриншот ошибки

Я понимаю, что означает ошибка, что он попытался развернуть необязательное значение, потому что я принудительно развернул его, и он не смог найти значение Int в строке, которую я ему передал, но я не понимаю, почему я получаю ошибку, Значение строки 1, что очень четко целое число. Что я делаю неправильно?

2 ответа

Так как 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")

Как упомянул @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")
        }
    }
Другие вопросы по тегам