質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2818閲覧

xcode csvファイルを読み込む時にエラーが出る。

puprin0823

総合スコア11

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/06/30 00:06

編集2018/06/30 00:42

前提・実現したいこと

xcodeで四択問題を作っています。
そこでcsvファイルを読み込み配列に入れて実行しようとした時にエラーが出ました。
シュミレータを起動するときはエラーは出ません。
デバッグエリアで配列を見てみると配列には何も入っていません。
csvArrayにCSVファイルを読み込んで、questionArrayにcsvArrayをコンマ区切りにして入れています。
どうすればいいか教えてください。
あと、xcodeを使う際のcsvファイルの文字コードも教えてください。
UTF8かSHIFTJISだと思うのですがどちらかわかりません。
CSVファイルが原因ならcsvファイルも載せます。

発生している問題・エラーメッセージ

エラーメッセージ questionArray = csvArray[questionCount].components(separatedBy: ",")ここにThread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) デバッグエリアにfatal error: Index out of range と出ています

該当のソースコード

lang

1 2ソースコード 3// 4// QuizViewController.swift 5// 4taku 6// 7// Created by Satoru Ohguchi on 2018/02/03. 8// Copyright © 2018年 Satoru Ohguchi. All rights reserved. 9// 10 11import UIKit 12 13class QuizViewController: UIViewController { 14 15 //ユーザーが指定した時間(仮) 分 16 let userTimer:Int = 1 17 var count = 150 18 19 var timeLabel:UILabel! 20 var secondLabel:UILabel! 21 // 問題表示の接続 22 @IBOutlet weak var quizNumberLabel: UILabel! 23 @IBOutlet weak var uiButton1: UIButton! 24 @IBOutlet weak var uiButton2: UIButton! 25 @IBOutlet weak var uiButton3: UIButton! 26 @IBOutlet weak var uiButton4: UIButton! 27 28 @IBOutlet weak var quizQuestionLabel: UILabel! 29 // 正誤表示 30 @IBOutlet weak var answerImage: UIImageView! 31 32 //NSTimer *timer; //クイズ中の経過時間を生成する 33 //int countDown; //設定時間 34 35 // 問題を格納 36 var csvArray = [String]() 37 38 // 取り出した問題を格納 39 var questionArray = [String]() 40 41 // 定数 42 var questionCount = 0 // 出題数 43 var correctCount = 0 // 正解 44 let total = 10 // 出題数 45 var cnt = 0 //出題数のカウント 46 47 // 画面表示完了後に動くメソッド 48 override func viewDidLoad() { 49 super.viewDidLoad() 50 //ラベルを適当に用意しておく 51 //時間 52 timeLabel = UILabel() 53 timeLabel.frame = CGRect(x:260,y:30,width:40,height:50) 54 timeLabel.font = UIFont.systemFont(ofSize: 20) 55 timeLabel.textAlignment = .center 56 view.addSubview(timeLabel) 57 58 //秒 59 secondLabel = UILabel() 60 secondLabel.frame = CGRect(x:300,y:30,width:30,height:50) 61 secondLabel.font = UIFont.systemFont(ofSize: 20) 62 view.addSubview(secondLabel) 63 64 // 問題の読み込み 65 csvArray = loadCSV(filename: "mondaicopyutf8") 66 67 // 画面の初期化 68 answerImage.isHidden = true 69 70 // 問題表示 71 nextProblem() 72 } 73 override func viewDidAppear(_ animated: Bool) { 74 super.viewDidAppear(animated) 75 //画面が表示されたらタイマーを動かす 76 createTimer() 77 } 78 79 //タイマーの作成 80 func createTimer(){ 81 count = userTimer * 150 82 83 let timer = Timer.scheduledTimer(timeInterval: 1.0, 84 target: self, 85 selector: #selector(self.timerAction(sender:)), 86 userInfo: nil, 87 repeats: true) 88 timer.fire() 89 90 } 91 92 //タイマーの処理 93 @objc func timerAction(sender:Timer){ 94 count < 150 95 timeLabel.text = String(count) 96 secondLabel.text = "秒" 97 if count == 0{ 98 sender.invalidate() //止める 99 timeup() 100 } 101 count -= 1 102 } 103 104 105 // 正誤判定 106 @IBAction func btnAction(_ sender: UIButton) { 107 // 正解とボタンのタグ番号が同じなら正解 108 if sender.tag == Int(questionArray[5]) { 109 answerImage.image = UIImage(named: "correct.png") 110 correctCount += 1 111 } else { 112 answerImage.image = UIImage(named: "incorrect.png") 113 } 114 115 // 回答表示の有効化(0.5秒間) 116 answerImage.isHidden = false 117 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 118 self.answerImage.isHidden = true 119 } 120 121 // 次の問題文呼び出し 122 questionCount = Int(arc4random_uniform(31)) 123 cnt += 1 124 nextProblem() 125 } 126 127 // 問題表示 & 画面遷移 128 func nextProblem() { 129 // questionArrayの初期化 130 questionArray.removeAll(keepingCapacity: true) 131 132 if cnt < total { 133 // questionArrayに新規問題を格納 134 questionArray = csvArray[questionCount].components(separatedBy: ",") 135 // 表示内容をセット 136 quizNumberLabel.text = "第(cnt+1)問" 137 quizQuestionLabel.text = questionArray[0] 138 uiButton1.setTitle(questionArray[1], for: .normal) 139 uiButton1.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping 140 uiButton1.titleLabel!.numberOfLines = 4 141 uiButton1.titleLabel!.textAlignment = NSTextAlignment.center 142 uiButton2.setTitle(questionArray[2], for: .normal) 143 uiButton2.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping 144 uiButton2.titleLabel!.numberOfLines = 4 145 uiButton2.titleLabel!.textAlignment = NSTextAlignment.center 146 uiButton3.setTitle(questionArray[3], for: .normal) 147 uiButton3.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping 148 uiButton3.titleLabel!.numberOfLines = 4 149 uiButton3.titleLabel!.textAlignment = NSTextAlignment.center 150 uiButton4.setTitle(questionArray[4], for: .normal) 151 uiButton4.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping 152 uiButton4.titleLabel!.numberOfLines = 4 153 uiButton4.titleLabel!.textAlignment = NSTextAlignment.center 154 } 155 else { 156 // Storyboard Segue の Identifier を引数に定義して画面遷移 157 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 158 self.performSegue(withIdentifier: "toResultViewController", sender: nil) 159 } 160 } 161 } 162 163 func timeup(){ 164 if count == 0{ 165 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 166 self.performSegue(withIdentifier: "toResultViewController", sender: nil) 167 } 168 } 169 } 170 171 // Segue で値を渡す 172 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 173 let sVC: ResultViewController = (segue.destination as? ResultViewController)! 174 sVC.correct = correctCount 175 } 176 177 // CSVファイルの読み込み 178 func loadCSV(filename : String)->[String] { 179 180 // 返却値の初期化 181 var csvStr = [String]() 182 183 // CSVを読み込んでArrayに 184 // https://qiita.com/MYamate_jp/items/ce4a05e78aa23449fa1e 185 if let csvPath = Bundle.main.path(forResource: filename, ofType: "csv") { 186 do { 187 var csvData = try String(contentsOfFile: csvPath, encoding: String.Encoding.utf8) 188 csvData = csvData.replacingOccurrences(of: "\n", with: "") 189 csvStr = csvData.components(separatedBy: .newlines) 190 } catch let error as NSError { 191 print(error.localizedDescription) 192 } 193 } 194 195 return csvStr 196 } 197 198 override func didReceiveMemoryWarning() { 199 super.didReceiveMemoryWarning() 200 // Dispose of any resources that can be recreated. 201 } 202}

試したこと

ネットでcsvファイルについて調べましたが、一向に解決しませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。
Xcodeは最新バージョンです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasakiHori

2018/06/30 00:42

参照元にはない csvData = csvData.replacingOccurrences(of: "\n", with: "") を追加している意味は何ですか?
puprin0823

2018/06/30 00:43

その通りに直しました。
puprin0823

2018/06/30 01:01

xcodeを始めたばかりで、詳しいことはわからないのですが、その文は消したほうがいいのでしょうか?
guest

回答2

0

検証してみたところ、改行の部分で
csvData = csvData.replacingOccurrences(of: "\n", with: "")
がうまく働いていないようですね。
questionArray[0]の中にCSVの全ての要素が入ってしまっているようです。

例えばなのですが、
csvData = csvData.replacingOccurrences(of: " ", with: "\n")
として、csvファイルの行の末尾に全角スペース入れてあげると動くようになりました。
あまりスマートではないですが、参考にしていただければ幸いです。

投稿2018/07/23 10:32

編集2018/07/23 10:33
springer

総合スコア24

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「Index out of range」なので配列に対して、配列のサイズ以上のものを指定しているのでしょう。
エラーとなる行にブレークポイントを指定してcsvArrayの要素数とquestionCountを確認してはいかがでしょうか。
loadCSVで正しく読み込まれているかも確認した方が良いです。

投稿2018/06/30 09:17

nakasho_dev

総合スコア2655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

puprin0823

2018/07/10 08:12

確認したところ、loadcsvとcsvArrayとquestionCountには問題がありませんでした。 しかし、問題や回答を入れるquestionArrayには問題しか入っていませんでした。 どうすれば解決するでしょうか?
puprin0823

2018/07/10 08:17

他のcsvファイルを読み込ませたところloadcsvが正しく読み込めていないのでcsvarrayには何も入っていませんでした。
nakasho_dev

2018/07/10 12:30

loadCSV内をStep実行したらどうなります?例外発生していませんか。
puprin0823

2018/07/11 07:11

それはloadCsvにブレークポイントを付けるということでしょうか?
puprin0823

2018/07/13 06:30

わかりました、試してみます。
springer

2018/07/23 10:02

こちら同じ感じでエラーが出ているのですが、解決できましたか??
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問