gocarina / gocsv

The GoCSV package aims to provide easy CSV serialization and deserialization to the golang programming language
MIT License
1.99k stars 245 forks source link

[BUG] Fails if comma is present in a header name #235

Open Elijas opened 1 year ago

Elijas commented 1 year ago

It seems to fail when a comma is present in a header name. For example, given two headers:

Like in the following CSV file:

"header1_no_comma","header2,1_with_comma"
1.0,2.0
1.1,2.1

Reproduction

package main

import (
    "fmt"

    "github.com/gocarina/gocsv"
)

type csvRow struct {
    A string `csv:"a"`
    B string `csv:"b,c"`
}

func main() {
    rows := []*csvRow{}
    if err := gocsv.UnmarshalString("a,\"b,c\"\n1,2\n3,4", &rows); err != nil {
        panic(err)
    }

    for _, row := range rows {
        fmt.Printf("%+v\n", row)
    }
}

Actual output

&{A:1 B:}
&{A:3 B:}

Expected output

&{A:1 B:2}
&{A:3 B:4}
haton14 commented 1 year ago

@Elijas It seems that the behavior is as expected. It appears that the usage of the library is incorrect.

https://github.com/gocarina/gocsv/blob/6445c2b15027b1f609e5a5e908b7848a03bdb9fa/decode_test.go#L227-L253

s[0].string,slice[0].f,slice[1].s,s[1].float,a[0].s,array[0].float,a[1].s,array[1].float,ints[0],ints[1],ints[2]
s1,1.1,s2,2.2,s3,3.3,s4,4.4,1,2,3
type SliceStructSample struct {
    Slice       []SliceStruct  `csv:"s,slice" csv[]:"2"`
    Slice2      []SliceStruct  `csv:"sliceText"`
    SimpleSlice []int          `csv:"ints" csv[]:"3"`
    Array       [2]SliceStruct `csv:"a,array" csv[]:"2"`
}
type SliceStruct struct {
    String string  `csv:"s,string"`
    Float  float64 `csv:"f,float"`
}

SliceStructSample{
    Slice: []SliceStruct{
        {String: "s1", Float: 1.1},
        {String: "s2", Float: 2.2},
    },
    SimpleSlice: []int{1, 2, 3},
    Array: [2]SliceStruct{
        {String: "s3", Float: 3.3},
        {String: "s4", Float: 4.4},
    },
}
acls commented 1 year ago

@Elijas Have you tried setting the TagSeparator? https://github.com/gocarina/gocsv/blob/6445c2b15027b1f609e5a5e908b7848a03bdb9fa/csv.go#L36-L37

yuki2006 commented 1 year ago

I also faced the same issue. While TagSeparator indeed seems to provide a solution, the fact that it's a global variable is somewhat concerning. It would be fantastic if it could be an argument option for the unmarshal function instead.

shigetaichi commented 1 year ago

@Elijas @yuki2006 I have created a new package that allows the TagSeparator to be changed, and I have used gocsv as a reference for most of the csv generation process. (Thanks to all gocsv contributors.) I hope the ideas are helpful to you. https://github.com/shigetaichi/xsv