Swift遍历文本字符遇死循环与数组越界问题求助
嘿,我来帮你解决这两个头疼的问题——运行卡死(疑似死循环)和数组越界,顺便把区分0和X的逻辑给捋顺。
一、先搞定运行卡死的问题
你怀疑编码问题是完全合理的!如果你的Example.txt不是UTF-8编码(比如是Windows常用的GBK、UTF-16,或者带特殊字符的ASCII),用utf8编码读取会导致字符串解析异常,甚至触发奇怪的循环问题。另外,文件里的空行、多余换行符,或者强制解包path!隐藏的错误,也可能让App卡在加载界面。
给你几个修复步骤:
- 确认文件编码:用VS Code、Sublime这类编辑器打开
Example.txt,看右下角的编码标识,改成UTF-8后重新保存。 - 过滤无效行:读取后先把空行、纯空白的行过滤掉,避免处理无意义的内容。
- 安全解包+多编码尝试:别直接用
path!强制解包,用可选绑定更安全;如果UTF-8读取失败,试试ASCII等其他编码。
修改后的基础读取代码:
if let path = Bundle.main.path(forResource: "Example.txt", ofType: nil) { do { // 优先尝试UTF-8编码读取 let fileContents = try String(contentsOfFile: path, encoding: .utf8) // 过滤空行和仅含空白字符的行 let validLines = fileContents.components(separatedBy: .newlines) .filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty } for rowIndex in 0..<validLines.count { let line = validLines[rowIndex] // 分割后过滤掉空字符串(比如连续空格导致的无效元素) let elements = line.components(separatedBy: " ") .filter { !$0.isEmpty } for columnIndex in 0..<elements.count { print("列: \(columnIndex), 行: \(rowIndex)") } } } catch { print("UTF-8编码读取失败: \(error.localizedDescription)") // fallback到ASCII编码尝试 do { let fileContents = try String(contentsOfFile: path, encoding: .ascii) let validLines = fileContents.components(separatedBy: .newlines) .filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty } // 后续循环逻辑同上... } catch { print("ASCII编码读取也失败了: \(error.localizedDescription)") } } } else { print("找不到Example.txt文件,请确认文件已加入项目") }
二、修复数组越界,正确区分0和X
你第二个代码里的items[1]是硬编码了索引1,这肯定会越界啊!比如某一行分割后元素数量不足2,或者没过滤空行导致items是空数组,访问索引1直接就崩了。
正确的做法是用循环变量column访问当前元素,同时提前过滤无效元素:
if let path = Bundle.main.path(forResource: "Example.txt", ofType: nil) { do { let fileContents = try String(contentsOfFile: path, encoding: .utf8) let validLines = fileContents.components(separatedBy: .newlines) .filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty } for rowIndex in 0..<validLines.count { let elements = validLines[rowIndex].components(separatedBy: " ") .filter { !$0.isEmpty } // 去掉空字符串,避免无效元素 for columnIndex in 0..<elements.count { let currentElement = elements[columnIndex] if currentElement == "0" { print("行\(rowIndex), 列\(columnIndex): 0") } else if currentElement == "X" { print("行\(rowIndex), 列\(columnIndex): X") } else { print("行\(rowIndex), 列\(columnIndex): 未知字符 \(currentElement)") } } } } catch { print("加载地图出错: \(error.localizedDescription)") } }
三、额外优化:更可靠的字符遍历方式
用components(separatedBy: " ")容易因为连续空格、制表符出问题,不如直接遍历每行的字符,跳过空格就行,逻辑更简洁:
if let path = Bundle.main.path(forResource: "Example.txt", ofType: nil) { do { let fileContents = try String(contentsOfFile: path, encoding: .utf8) let validLines = fileContents.components(separatedBy: .newlines) .filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty } for rowIndex in 0..<validLines.count { let line = validLines[rowIndex] var columnIndex = 0 for char in line { if char == " " { // 跳过空格,只处理有效字符 continue } if char == "0" { print("行\(rowIndex), 列\(columnIndex): 0") } else if char == "X" { print("行\(rowIndex), 列\(columnIndex): X") } columnIndex += 1 } } } catch { print("加载地图出错: \(error.localizedDescription)") } }
内容的提问来源于stack exchange,提问作者E. Huckabee
相关产品推荐
相关产品推荐

