Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Elijas opened this issue Feb 6, 2023 · 4 comments
Open

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

Elijas opened this issue Feb 6, 2023 · 4 comments

Comments

@Elijas
Copy link

Elijas commented Feb 6, 2023

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

  • header1_no_comma
  • header2,1_with_comma

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}
@Elijas Elijas changed the title [BUG] Comma in header name [BUG] Fails if comma is present in a header name Feb 6, 2023
@haton14
Copy link
Contributor

haton14 commented Apr 26, 2023

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

gocsv/decode_test.go

Lines 227 to 253 in 6445c2b

func Test_readTo_slice_structs(t *testing.T) {
b := bytes.NewBufferString(`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`)
d := newSimpleDecoderFromReader(b)
var samples []SliceStructSample
err := readTo(d, &samples)
if err != nil {
t.Fatalf("failed to unmarshal: %v", err)
}
expected := 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},
},
}
if !reflect.DeepEqual(expected, samples[0]) {
t.Fatalf("expected \n sample: %v\n got: %v", expected, samples[0])
}
}

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
Copy link
Contributor

acls commented Apr 26, 2023

@Elijas Have you tried setting the TagSeparator?

gocsv/csv.go

Lines 36 to 37 in 6445c2b

// TagSeparator defines seperator string for multiple csv tags in struct fields
var TagSeparator = ","

@yuki2006
Copy link

yuki2006 commented Jul 6, 2023

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
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants