Rumah > Soal Jawab > teks badan
用swift写了一个程序,添加了一个学生成绩管理的sqlite数据库。用的是XCODE7.3.1。
但是总会在labelId.text = "(arrStu[n].id)"处报错“fatal error: Index out of range”。
请大神们帮忙看看代码
import UIKit
class ViewController: UIViewController {
//数据库结构:主索引 姓名 语文成绩 数学成绩
struct stu {
var id:Int32
var name:String
var chinese:Int32
var math:Int32
init(id:Int32,name:String,chinese:Int32,math:Int32) {
self.id = id
self.name = name
self.chinese = chinese
self.math = math
}
}
/*定义变量*/
var arrStu:Array<stu> = []//存储数据库的数组
var db:COpaquePointer = nil
var statement:COpaquePointer = nil
var sql:NSString = ""//SQL指令
var currentStu = 0//当前数据
@IBOutlet var labelId: UILabel!//显示数据编号
@IBOutlet var textName: UITextField!//输入姓名
@IBOutlet var textChinese: UITextField!//输入语文成绩
@IBOutlet var textMath: UITextField!//输入数学成绩
@IBOutlet var tableViewSqlite: UITableView!
@IBOutlet var buttonInsert: UIButton!
@IBOutlet var buttonWrite: UIButton!
/*表格的设置*/
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return arrStu.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell",forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = " 姓名:\(arrStu[indexPath.row].name)"
cell.detailTextLabel?.text = " 编号:\(arrStu[indexPath.row].id) 语文:\(arrStu[indexPath.row].chinese) 数学:\(arrStu[indexPath.row].math)"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
buttonToggle(true, writeAble: false)
currentStu = indexPath.row
showSingle(currentStu)
}
/*定义对话框*/
func alertView(alertView:UIAlertView,clickedButtonAtIndex buttonIndex:Int) {
if alertView.title == " 更新 " {
switch (buttonIndex) {
case 0://单击“确定”按钮的处理
//确定更新数据,更新数据库
let sqltem1:String = "UPDATE class101 SET s_name ='" + textName.text! + "',s_math=" + textChinese.text!
let sqltem2:String = ",s_math=" + textMath.text! + "WHERE s_id=" + labelId.text!
sql = sqltem1 + sqltem2
statement = nil
sqlite3_prepare_v2(db, sql.UTF8String, -1, &statement, nil)
if sqlite3_step(statement) == SQLITE_DONE {
alertMsg(" 成功 ", msgStr: " 数据库更新成功! ")
} else {
alertMsg(" 失败 ", msgStr: " 数据库更新失败! ")
}
//更新数组
arrStu[currentStu].name = textName.text!
arrStu[currentStu].chinese = Int32(Int(textChinese.text!)!)
arrStu[currentStu].math = Int32(Int(textMath.text!)!)
tableViewSqlite.reloadData()
default:
break
}
} else if alertView.title == " 删除 " {
switch (buttonIndex) {
case 0://单击“确定”按钮的处理
//确定删除数据,更新数据库
sql = "DELETE FROM class101 WHERE s_id=" + labelId.text!
statement = nil
sqlite3_prepare_v2(db, sql.UTF8String, -1, &statement, nil)
if sqlite3_step(statement) == SQLITE_DONE {
alertMsg(" 成功 ", msgStr: " 数据库删除成功! ")
} else {
alertMsg(" 失败 ", msgStr: " 数据库删除失败! ")
}
arrStu.removeAtIndex(currentStu)
tableViewSqlite.reloadData()
//数据删除后,显示下一笔
if currentStu == arrStu.count {
currentStu -= 1
}
showSingle(currentStu)
default:
break
}
}
}
/*创建自定义函数*/
func showSingle(n:Int) {//显示单笔数据
labelId.text = "\(arrStu[n].id)"
textName.text = arrStu[n].name
textChinese.text = "\(arrStu[n].chinese)"
textMath.text = "\(arrStu[n].math)"
}
func buttonToggle(insertAble:Bool,writeAble:Bool) -> Void {
buttonInsert.enabled = insertAble
buttonWrite.enabled = writeAble
}
func alertMsg(titleStr:String,msgStr:String) -> Void {
let alertView:UIAlertView = UIAlertView(title:titleStr,message: msgStr,delegate: self,cancelButtonTitle: " 确定 ")
alertView.show()
}
/*页面载入时*/
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
buttonToggle(true, writeAble: false)
//第一次执行时将数据库复制到Documents文件夹
let fm:NSFileManager = NSFileManager()
db = nil
let src:String = NSBundle.mainBundle().pathForResource("student", ofType: "sqlite")!
let dst:String = NSHomeDirectory() + "/Documents/student.sqlite"
if !fm.fileExistsAtPath(dst) {
try! fm.copyItemAtPath(src, toPath: dst)
}
//连接及打开数据库
if sqlite3_open(dst, &db) != SQLITE_OK {
alertMsg(" 失败 ", msgStr: " 无法打开数据库! ")
}
//逐笔读取数据行
while sqlite3_step(statement) == SQLITE_ROW {
let id = sqlite3_column_int(statement, 0)
let temName = sqlite3_column_text(statement, 1)
let name = String.fromCString(UnsafePointer<CChar>(temName))
let chinese = sqlite3_column_int(statement, 2)
let math = sqlite3_column_int(statement, 3)
let student:stu = stu(id: id, name: name!, chinese: chinese, math: math)
arrStu.append(student)//将数据行存入数组
}
sqlite3_finalize(statement)
tableViewSqlite.reloadData()
showSingle(0)//开始时显示第一笔数据
}
/*按键的触发事件*/
@IBAction func modifyClick(sender: UIButton) {//修改
let alertModify:UIAlertView = UIAlertView()
alertModify.title = " 更新 "
alertModify.message = " 确定要更新数据吗? "
alertModify.delegate = self
alertModify.addButtonWithTitle(" 确定 ")
alertModify.addButtonWithTitle(" 取消 ")
alertModify.show()
}//更新数据
@IBAction func deleteClick(sender: UIButton) {//删除
if arrStu.count > 1 {//数据大于1笔才允许删除
let alertDelete:UIAlertView = UIAlertView()
alertDelete.title = " 删除 "
alertDelete.message = " 确定要删除数据吗? "
alertDelete.delegate = self
alertDelete.addButtonWithTitle(" 确定 ")
alertDelete.addButtonWithTitle(" 取消 ")
alertDelete.show()
} else {
self.alertMsg(" 失败 ", msgStr: " 只有一笔数据时不可删除! ")
}
}
@IBAction func insertClick(sender: UIButton) {//新增
buttonToggle(false, writeAble: true)
labelId.text = ""
textName.text = ""
textChinese.text = ""
textMath.text = ""
}
@IBAction func writeClick(sender: UIButton) {//写入
buttonToggle(true, writeAble: false)
sql = "INSERT INTO class101 (s_name, s_chinese, s_math) VALUES ('" + textName.text! + "'," + textChinese.text! + "," + textMath.text! + ");"
statement = nil
sqlite3_prepare_v2(db, sql.UTF8String, -1, &statement, nil)
if sqlite3_step(statement) == SQLITE_DONE {
alertMsg(" 成功 ",msgStr:" 数据库新增成功! ")
} else {
alertMsg(" 失败 ",msgStr:" 数据库新增失败! ")
}
let id = Int32(sqlite3_last_insert_rowid(db))
let name = textName.text
let chinese = Int32(Int(textChinese.text!)!)
let math = Int32(Int(textMath.text!)!)
let student:stu = stu(id:id, name:name!, chinese:chinese, math:math)
arrStu.append(student)//将数据行存入数组
tableViewSqlite.reloadData()
showSingle(arrStu.count - 1)
currentStu = arrStu.count - 1
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ringa_lee2017-04-18 09:06:25
Selesai! ! !
Saya cuba menambah sekeping kod semasa halaman dimuatkan, supaya paparan jadual akan memaparkan pangkalan data sedia ada dalam pangkalan data semasa memuatkan, supaya tiada ralat akan dilaporkan. Besar kemungkinan jadual kod asal tidak memaparkan data semasa memuatkan, jadi tiada data dalam jadual, jadi fungsi seterusnya akan melaporkan ralat "ralat maut: Indeks di luar julat".
/*Apabila halaman dimuatkan*/
mengatasi fungsi viewDidLoad() {
super.viewDidLoad()
// Lakukan sebarang persediaan tambahan selepas memuatkan paparan, lazimnya dari mata pena.
buttonToggle(true, writeAble: false)
//Salin pangkalan data ke folder Dokumen apabila melaksanakan buat kali pertama
biarkan fm:NSFileManager = NSFileManager()
db = tiada
biarkan src:String = NSBundle.mainBundle().pathForResource("pelajar", ofType: "sqlite"!
biarkan dst:String = NSHomeDirectory() + "/Documents/student.sqlite"
jika !fm.fileExistsAtPath(dst) {
cuba! fm.copyItemAtPath(src, toPath: dst)
}
//Sambung dan buka pangkalan data
jika sqlite3_open(dst, &db) != SQLITE_OK {
alertMsg("Gagal", msgStr: "Tidak dapat membuka pangkalan data!")
}
let sql:NSString = "SELECT * FROM class101"
jika sqlite3_prepare_v2(db,sql.UTF8String,-1,&statement,nil) != SQLITE_OK {
let alertView:UIAlertView = UIAlertView(title:" Failed to read ",message: " Failed to read the database! ",delegate: self,cancelButtonTitle: " OK ")
alertView.show()
keluar(1)
}
arrStu.removeAll(keepCapacity: true)
//Baca baris data satu demi satu
manakala sqlite3_step(penyataan) == SQLITE_ROW {
biarkan id = sqlite3_column_int(penyataan, 0)
biarkan temName = sqlite3_column_text(penyataan, 1)
biarkan nama = String.fromCString(UnsafePointer<CChar>(temName))
biarkan cina = sqlite3_column_int(penyataan, 2)
biarkan matematik = sqlite3_column_int(penyataan, 3)
biarkan pelajar:stu = stu(id: id, nama: nama!, cina: cina, matematik: matematik)
arrStu.append(pelajar)//Simpan baris data ke dalam tatasusunan
}
sqlite3_finalize(statement)
tableViewSqlite.reloadData()
showSingle(0)//Paparkan data pertama pada permulaan
}
Sesiapa sahaja yang berminat boleh membantu saya melihat di mana saya perlu menambah baik Apabila keseluruhan kod berjalan, mengklik pada titik pengubahsuaian akan muncul kotak dialog yang tidak berjaya.
PHP中文网2017-04-18 09:06:25
Berdasarkan gesaan, ralat sepatutnya adalah bahawa subskrip keluar dari had semasa mengakses arrStu Bolehkah anda menyemak panjang arrStu? Juga, jika tidak, mengapa ia akan membawa kepada situasi di mana saya perlu mengakses elemen yang tidak wujud dalam tatasusunan?