Greg
Greg

Reputation: 471

strings.Split in Go

The file names.txt consists of many names in the form of:

"KELLEE","JOSLYN","JASON","INGER","INDIRA","GLINDA","GLENNIS"

Does anyone know how to split the string so that it is individual names separated by commas?

KELLEE,JOSLYN,JASON,INGER,INDIRA,GLINDA,GLENNIS

The following code splits by comma and leaves quotes around the name, what is the escape character to split out the ". Can it be done in one Split statement, splitting out "," and leaving a comma to separate?

package main

import "fmt"
import "io/ioutil"
import "strings"

func main() {
        fData, err := ioutil.ReadFile("names.txt")  // read in the external file
    if err != nil {
        fmt.Println("Err is ", err)     // print any error
    }
    strbuffer := string(fData)  // convert read in file to a string

    arr := strings.Split(strbuffer, ",")

    fmt.Println(arr)

}

By the way, this is part of Project Euler problem # 22. http://projecteuler.net/problem=22

Upvotes: 14

Views: 20904

Answers (2)

tux21b
tux21b

Reputation: 94659

Jeremy's answer is basically correct and does exactly what you have asked for. But the format of your "names.txt" file is actually a well known and is called CSV (comma separated values). Luckily, Go comes with an encoding/csv package (which is part of the standard library) for decoding and encoding such formats easily. In addition to your + Jeremy's solution, this package will also give exact error messages if the format is invalid, supports multi-line records and does proper unquoting of quoted strings.

The basic usage looks like this:

package main

import (
    "encoding/csv"
    "fmt"
    "io"
    "os"
)

func main() {
    file, err := os.Open("names.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    defer file.Close()
    reader := csv.NewReader(file)
    for {
        record, err := reader.Read()
        if err == io.EOF {
            break
        } else if err != nil {
            fmt.Println("Error:", err)
            return
        }

        fmt.Println(record) // record has the type []string
    }
}

There is also a ReadAll method that might make your program even shorter, assuming that the whole file fits into the memory.

Update: dystroy has just pointed out that your file has only one line anyway. The CSV reader works well for that too, but the following, less general solution should also be sufficient:

for {
    if n, _ := fmt.Fscanf(file, "%q,", &name); n != 1 {
        break
    }
    fmt.Println("name:", name)
}

Upvotes: 19

Jeremy Wall
Jeremy Wall

Reputation: 25237

Split doesn't remove characters from the substrings. Your split is fine you just need to process the slice afterwards with strings.Trim(val, "\"").

for i, val := range arr {
  arr[i] = strings.Trim(val, "\"")
}

Now arr will have the leading and trailing "s removed.

Upvotes: 9

Related Questions