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")
}
}