Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将文本文件中的数据保存在数组和/或字典中_Ios_Xcode_Swift - Fatal编程技术网

Ios 将文本文件中的数据保存在数组和/或字典中

Ios 将文本文件中的数据保存在数组和/或字典中,ios,xcode,swift,Ios,Xcode,Swift,我等待一个编程步骤。我希望你能帮助我 我在一个文本文件中得到了以下行: #Objekt Objektnr; 1000000; Filialname; Dresden; Filialeemail; email@email.com; #Baustelle Anschrift1;; Anschrift2;Juwelier Schubert; Strasse;Theresienstrafle 7; Land;DE; Ort;TheTown; PLZ;12345; .... 我有以下函数将文件数据带到

我等待一个编程步骤。我希望你能帮助我

我在一个文本文件中得到了以下行:

#Objekt
Objektnr; 1000000;
Filialname; Dresden;
Filialeemail; email@email.com;

#Baustelle
Anschrift1;;
Anschrift2;Juwelier Schubert;
Strasse;Theresienstrafle 7;
Land;DE;
Ort;TheTown;
PLZ;12345;

....
我有以下函数将文件数据带到数组或字典中。在另一个函数中,我将数据保存到本地CoreData数据库

func startImportTextfile(fileName: String, fileDir: String) -> Bool {

    var filePath : String = folderDocuments.stringByAppendingPathComponent(fileDir)
    var fileNameWithPath = filePath.stringByAppendingPathComponent(fileName)

    var fullImportContent = String(contentsOfFile: fileNameWithPath, encoding: NSUTF8StringEncoding, error: nil)

    if(fullImportContent != "")
    {

        var stringArray = fullImportContent!.componentsSeparatedByString("\n")
        var stringArrayCompleteData = Dictionary<String, Array<Any>>()
        var arrIndexSection : String = "NoHeader"

        for singleRow in stringArray
        {
            if(singleRow != "")
            {
                switch singleRow {
                    case "#Header":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Objekt":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Baustelle":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Auftraggeber":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Architekt":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Vermittler":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Regulierer":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Versicherung":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Kontaktstellen":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    case "#Dateien":
                        arrIndexSection = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    default:
                        //Here the multiple array would be filled
                        var arrSingleRow = singleRow.componentsSeparatedByString(";")

                        if( arrSingleRow.count > 0  )
                        {
                            if( arrIndexSection == "Kontaktstellen" )
                            {
                                //TODO: Kontaktstellen einlesen

                                //#Kontaktstellen
                                //Baustelle;0;348873;;;;0
                                //Baustelle;0;381263;;Albrecht;0815;0
                                //Regulierer/SV;0;171979;Josef;Eder;08546/911055;0
                                println( "Kontaktstellendaten" )
                                println( singleRow )
                            }
                            else if( arrIndexSection == "Dateien" )
                            {
                                //TODO: Dateien einlesen

                                //#Dateien
                                //11022015090007_BEmail_INNNUE_21102014141534.pdf; 99; Email an asdfasdf@sdf.de

                                println( "Dateiendaten" )
                                println( singleRow )
                            }
                            else
                            {
                                stringArrayCompleteData[arrIndexSection] = [arrSingleRow[0]: arrSingleRow[1]]
                            }
                        }
                }
            }
        }

        for key in stringArrayCompleteData {
            println("Key: \(key)")
        }
        return true
    }
    else
    {
        return false
    }

}
但是我不知道如何声明stringArrayCompleteData

也许我必须改变这种歧视

var stringArrayCompleteData = Dictionary<String, Array<Any>>()
var stringArrayCompleteData=Dictionary()

var stringArrayCompleteData=Array()

感谢每一个小小的帮助

我放置了一个包含您的数据的文本文件,并保存在文档目录中的文本文件中,将文本文件名和目录路径传递给函数,函数以字典格式将数据返回到字典中

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()

        let fileDirectory : [String] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as [String]

        var fileDir = fileDirectory[0]

        var returnedDictionary : Dictionary = self.startImportTextfile("textdata", fileDir: fileDir)

        println(returnedDictionary)

        var keyDictionary : Dictionary! = returnedDictionary["Objekt"]

        println(keyDictionary["Objektnr"] as String!)
    }

    func startImportTextfile(fileName: String, fileDir: String) -> Dictionary<String,Dictionary<String,String>> {


        let fileNameWithPath :String! = fileDir.stringByAppendingPathComponent(fileName)

        var err: NSError?

        var currentKey : String!

        let fullImportContent :String! = String.stringWithContentsOfFile(fileNameWithPath!, encoding: NSUTF8StringEncoding, error: &err)

        var dataDictionary = [String : Dictionary <String,String>]()

        if(fullImportContent != "")
        {
            var singleLineArray = fullImportContent!.componentsSeparatedByString("\n")

            for singleRow in singleLineArray
            {
                if(singleRow != "")
                {
                    switch singleRow
                    {

                    case "#Header","#Objekt","#Baustelle","#Auftraggeber","#Architekt","#Vermittler","#Regulierer","#Versicherung","#Kontaktstellen","#Dateien":
                        currentKey = singleRow.stringByReplacingOccurrencesOfString("#", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
                        dataDictionary[currentKey] = Dictionary <String,String>()

                    default:
                        var arrayForSingleRow = singleRow.componentsSeparatedByString(";")

                        if( arrayForSingleRow.count > 0  )
                        {
                            var sampledict : Dictionary! = dataDictionary[currentKey]

                            sampledict[arrayForSingleRow[0]] = arrayForSingleRow[1]

                            dataDictionary[currentKey] = sampledict

                        }
                    }
                }
            }
        }

        return dataDictionary

    }

}
导入UIKit
类ViewController:UIViewController{
重写func viewDidLoad(){
super.viewDidLoad()
将fileDirectory:[String]=NSSearchPathForDirectoriesInDomains(.DocumentDirectory、.UserDomainMask,true)设为[String]
var fileDir=fileDirectory[0]
var returnedDictionary:Dictionary=self.startImportTextfile(“textdata”,fileDir:fileDir)
println(返回的字典)
var键字典:字典!=returnedDictionary[“Objekt”]
println(作为字符串的keyDictionary[“Objektnr”])
}
func startImportTextfile(fileName:String,fileDir:String)->字典{
让fileNameWithPath:String!=fileDir.stringByAppendingPathComponent(文件名)
变量错误:n错误?
var currentKey:String!
让fullImportContent:String!=String.stringWithContentsOfFile(文件名WithPath!,编码:NSUTF8StringEncoding,错误:&err)
var dataDictionary=[String:Dictionary]()
如果(fullImportContent!=“”)
{
var singleLineArray=fullImportContent!.componentsSeparatedByString(“\n”)
对于singleLineArray中的singleRow
{
如果(单列!=“”)
{
单列交换机
{
案例“#Header”、“#Objekt”、“#Baustelle”、“#Auftraggeber”、“#Architekt”、“#verittler”、“#regulaier”、“#Versicherung”、“#Kontaktstellen”、“#Dateien”:
currentKey=singleRow.StringByReplacingOfString(#),带字符串:“”,选项:NSStringCompareOptions.LiteralSearch,范围:nil)
dataDictionary[currentKey]=字典()
违约:
var arrayForSingleRow=singleRow.Components由字符串(“;”)分隔
如果(arrayForSingleRow.count>0)
{
var sampledict:Dictionary!=数据字典[currentKey]
sampledict[arrayForSingleRow[0]]=arrayForSingleRow[1]
dataDictionary[currentKey]=sampledict
}
}
}
}
}
返回数据字典
}
}
执行后,我得到以下输出:

[Objekt:[文件名:德累斯顿,文件编号:1000000,文件电子邮件:email@],鲍斯特勒:[邮政编码:12345,港口:镇,土地:德,安什里夫特1:,街道:特里西恩斯特拉7楼,安什里夫特2:朱韦利埃·舒伯特]] 一百万

其中,Objekt是键,它包含一个字典值,您可以从该字典访问Objektnr,就像我在viewDidLoad中所做的那样


链接到文本文件:

看起来您的猜测是正确的,您的意思是将
stringArrayCompleteData
声明为一个真正的字典字典,并将
Any
作为字典的值类型。顺便说一下,您可以将该类型声明为
[String:[String:Any]]

但是,您是否只想将细节存储为字符串?或者你打算把数字解析成整数?如果您想要一些更强类型的值集,作为使用
Any
作为数据类型的替代方法,您可能需要考虑使用

这是一个版本的代码,它将存储数据记录并将它们插入密钥下。这可以整理很多,但也使用一些你可能会发现有用的快捷功能

import Foundation
let folderDocuments = "/"

// rather than return true/false, you could return the data as an optional
func startImportTextfile(fileName: String, fileDir: String) -> [String: [String:String]]? {

    let filePath: String = folderDocuments.stringByAppendingPathComponent(fileDir)
    let fileNameWithPath = filePath.stringByAppendingPathComponent(fileName)

    var error: NSError?
    let fullImportContent = String(contentsOfFile: fileNameWithPath, encoding: NSUTF8StringEncoding, error: &error)

    if let data = fullImportContent where !data.isEmpty   {

        let stringArray = split(data) { $0 == "\n" }
        var completeData: [String: [String:String]] = [:]
        var sectionEntries: [String:String] = [:]
        var arrIndexSection: String? = nil

        for singleRow in stringArray {
            // first is an easy and safe way to check if first character
            // has a specific value, whilst handling empty strings
            if first(singleRow) == "#" {
                // insert records from previous section
                if let header = arrIndexSection {
                    completeData[header] = sectionEntries
                }
                // start a new section
                // dropFirst removes the first "#"
                arrIndexSection = dropFirst(singleRow)
                sectionEntries = [:]
            }
            else {
                let arrSingleRow = split(singleRow) { $0 == ";" }

                if( arrSingleRow.count > 0  ) {
                    switch arrIndexSection {
                    case .Some("Kontaktstellen"):
                        //TODO: Kontaktstellen einlesen
                        println( "Kontaktstellendaten" )
                        println( singleRow )
                    case .Some("Dateien"):
                        //TODO: Dateien einlesen
                        println( "Dateiendaten" )
                        println( singleRow )
                    default:
                        if let label = first(arrSingleRow) {
                            sectionEntries[label] = first(dropFirst(arrSingleRow)) ?? ""
                        }
                    }
                }
            }
        }

        if let header = arrIndexSection {
            completeData[header] = sectionEntries
        }

        return completeData
    }

    println("fail: \(error)")
    return nil
}

if let data = startImportTextfile(Process.arguments[1], Process.arguments[2]) {
    for (key,value) in data {
        println("Key: \(key)\nData: \(value)")
    }
}

嗨,罗兰-我的建议是将文本分成不同的部分,并将每个部分放入一个结构中。例如,您可以定义一个Objekt结构,该结构包含3个属性:objektnr、filialname和FilialEmail

例如,可以使用根Person结构创建结构树。Person结构将包含与Objekt结构实例、Bastille结构实例等对应的属性


下面是一些定义结构的示例代码:

struct Person:Printable {
    init() {
    }
    var objektStruct:Objekt?
    var baustelleStruct:Baustelle?


    var description:String {
        get {
            let objektStructDescription = objektStruct != nil ? objektStruct!.description : ""
            let baustelleStructDescription = baustelleStruct != nil ? baustelleStruct!.description : ""
            return "\(objektStructDescription)\n\n\(baustelleStructDescription)"
        }
    }
}

struct Objekt:Printable {
    var objektnr:Int = 0
    var filialname:String = ""
    var filialeemail:String = ""

    init(text:String) {
        // Divide the text into an array of lines
        let textLinesArray:[String] = text.componentsSeparatedByString("\n")

        // Loop through each line and set the corresponding property
        for textLine:String in textLinesArray {
            // Separate the components of the line at each ";" character
            var components:[String] = textLine.componentsSeparatedByString(";")
            components = components.map({ (componentString:String) -> String in
                return componentString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
            })

            // Get the key and value for the line.
            let key:String = components.count > 0 ? components[0] : ""
            let value:String = components.count > 1 ? components[1] : ""

            // Based on the key, set the appropriate property value
            switch key {
            case "Objektnr":
                if let valueAsInt = value.toInt() {
                    objektnr = valueAsInt
                }
            case "Filialname":
                filialname = value
            case "Filialeemail":
                filialeemail = value
            default:
                break
            }
        }
    }

    var description:String {
        get {
            return "*Objekt*\n Objektnr = \(objektnr)\n Filialname = \(filialname)\n Filialeemail = \(filialeemail)"
        }
    }
}

struct Baustelle:Printable {
    var anschrift1:String = ""
    var anschrift2:String = ""
    var strasse:String = ""
    var land:String = ""
    var ort:String = ""
    var plz:Int = 0

    init(text:String) {
        // Divide the text into an array of lines
        let textLinesArray:[String] = text.componentsSeparatedByString("\n")

        // Loop through each line and set the corresponding property
        for textLine:String in textLinesArray {
            // Separate the components of the line at each ";" character
            var components:[String] = textLine.componentsSeparatedByString(";")
            components = components.map({ (componentString:String) -> String in
                return componentString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
            })

            // Get the key and value for the line.
            let key:String = components.count > 0 ? components[0] : ""
            let value:String = components.count > 1 ? components[1] : ""

            // Based on the key, set the appropriate property value
            switch key {
            case "Anschrift1":
                anschrift1 = value
            case "Anschrift2":
                anschrift2 = value
            case "Strasse":
                strasse = value
            case "Land":
                land = value
            case "Ort":
                ort = value
            case "PLZ":
                if let valueAsInt = value.toInt() {
                    plz = valueAsInt
                }
            default:
                break
            }
        }
    }

    var description:String {
        get {
            return "*Baustelle*\n Anschrift1 = \(anschrift1)\n Anschrift2 = \(anschrift2)\n Strasse = \(strasse)\n Land = \(land)\n Ort = \(ort)\n PLZ = \(plz)"
        }
    }
}
let text = String(contentsOfFile: "/Users/markstone/Downloads/textdata.txt")!

// Divide the text at each double newline into multiline sections.
// Eg., the arrayOfTextSections[0] will be the multiline string:
//      #Objekt
//      Objektnr; 1000000;
//      Filialname; Dresden;
//      Filialeemail; email@
let arrayOfTextSections = text.componentsSeparatedByString("\n\n")

// Create an empty Person struct instance. We'll fill it in the loop below
var person = Person()

for textSection in arrayOfTextSections {
    // For each text section, find out the heading (eg., #Objekt or #Baustelle).
    let sectionStringArray = textSection.componentsSeparatedByString("\n")
    let sectionHeading = sectionStringArray[0]

    switch sectionHeading {
    case "#Objekt":
        // Create a new instance of the Objekt using the multiline text in this section, and set this instance to the person.objektStruct property.
        person.objektStruct = Objekt(text: textSection)
    case "#Baustelle":
        // Create a new instance of the Baustelle using the multiline text in this section, and set this instance to the person.baustelleStruct property.
        person.baustelleStruct = Baustelle(text: textSection)
    default:
        break
    }
}

print(person)
我为Objekt和baustele编写了init方法,这样就可以提供整个文本部分,而struct负责将其解析为不同的属性


下面是使用上述结构的一些示例代码:

struct Person:Printable {
    init() {
    }
    var objektStruct:Objekt?
    var baustelleStruct:Baustelle?


    var description:String {
        get {
            let objektStructDescription = objektStruct != nil ? objektStruct!.description : ""
            let baustelleStructDescription = baustelleStruct != nil ? baustelleStruct!.description : ""
            return "\(objektStructDescription)\n\n\(baustelleStructDescription)"
        }
    }
}

struct Objekt:Printable {
    var objektnr:Int = 0
    var filialname:String = ""
    var filialeemail:String = ""

    init(text:String) {
        // Divide the text into an array of lines
        let textLinesArray:[String] = text.componentsSeparatedByString("\n")

        // Loop through each line and set the corresponding property
        for textLine:String in textLinesArray {
            // Separate the components of the line at each ";" character
            var components:[String] = textLine.componentsSeparatedByString(";")
            components = components.map({ (componentString:String) -> String in
                return componentString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
            })

            // Get the key and value for the line.
            let key:String = components.count > 0 ? components[0] : ""
            let value:String = components.count > 1 ? components[1] : ""

            // Based on the key, set the appropriate property value
            switch key {
            case "Objektnr":
                if let valueAsInt = value.toInt() {
                    objektnr = valueAsInt
                }
            case "Filialname":
                filialname = value
            case "Filialeemail":
                filialeemail = value
            default:
                break
            }
        }
    }

    var description:String {
        get {
            return "*Objekt*\n Objektnr = \(objektnr)\n Filialname = \(filialname)\n Filialeemail = \(filialeemail)"
        }
    }
}

struct Baustelle:Printable {
    var anschrift1:String = ""
    var anschrift2:String = ""
    var strasse:String = ""
    var land:String = ""
    var ort:String = ""
    var plz:Int = 0

    init(text:String) {
        // Divide the text into an array of lines
        let textLinesArray:[String] = text.componentsSeparatedByString("\n")

        // Loop through each line and set the corresponding property
        for textLine:String in textLinesArray {
            // Separate the components of the line at each ";" character
            var components:[String] = textLine.componentsSeparatedByString(";")
            components = components.map({ (componentString:String) -> String in
                return componentString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
            })

            // Get the key and value for the line.
            let key:String = components.count > 0 ? components[0] : ""
            let value:String = components.count > 1 ? components[1] : ""

            // Based on the key, set the appropriate property value
            switch key {
            case "Anschrift1":
                anschrift1 = value
            case "Anschrift2":
                anschrift2 = value
            case "Strasse":
                strasse = value
            case "Land":
                land = value
            case "Ort":
                ort = value
            case "PLZ":
                if let valueAsInt = value.toInt() {
                    plz = valueAsInt
                }
            default:
                break
            }
        }
    }

    var description:String {
        get {
            return "*Baustelle*\n Anschrift1 = \(anschrift1)\n Anschrift2 = \(anschrift2)\n Strasse = \(strasse)\n Land = \(land)\n Ort = \(ort)\n PLZ = \(plz)"
        }
    }
}
let text = String(contentsOfFile: "/Users/markstone/Downloads/textdata.txt")!

// Divide the text at each double newline into multiline sections.
// Eg., the arrayOfTextSections[0] will be the multiline string:
//      #Objekt
//      Objektnr; 1000000;
//      Filialname; Dresden;
//      Filialeemail; email@
let arrayOfTextSections = text.componentsSeparatedByString("\n\n")

// Create an empty Person struct instance. We'll fill it in the loop below
var person = Person()

for textSection in arrayOfTextSections {
    // For each text section, find out the heading (eg., #Objekt or #Baustelle).
    let sectionStringArray = textSection.componentsSeparatedByString("\n")
    let sectionHeading = sectionStringArray[0]

    switch sectionHeading {
    case "#Objekt":
        // Create a new instance of the Objekt using the multiline text in this section, and set this instance to the person.objektStruct property.
        person.objektStruct = Objekt(text: textSection)
    case "#Baustelle":
        // Create a new instance of the Baustelle using the multiline text in this section, and set this instance to the person.baustelleStruct property.
        person.baustelleStruct = Baustelle(text: textSection)
    default:
        break
    }
}

print(person)
print(person)
打印以下输出:

*Objekt*
 Objektnr = 0
 Filialname =  Dresden
 Filialeemail =  email@email.com

*Baustelle*
 Anschrift1 = 
 Anschrift2 = Juwelier Schubert
 Strasse = Theresienstrafle 7
 Land = DE
 Ort = TheTown
 PLZ = 12345


使用这种方法,很容易将结构实例转换为核心数据存储的托管对象。

您的文本文件是否将包含与您提供的格式相同的数据?唯一的问题是,Objektnr=0不正确,因为字符串中的数字为1000000。int是这个长数字的错误类型吗?哦,对不起,问题是在“;”处拆分每一行之后字符,我没有删除任何前导空格。为了解决这个问题,我对上面的Objekt和Baustelle结构的init方法进行了修改。