関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。
encoding/csvパッケージを利用してCSV処理を書く際に、たまに列が不揃いの場合でも読み取ってほしいときがあります。
そのような場合は、csv.Reader.FieldsPerRecordに「負の値」を設定するとエラーにならずに読み取りを行ってくれます。
csv.Reader.FieldsPerRecordは、設定する値によって挙動が変わるので仕様を知っておくと便利。フィールド定義のコメントには以下のようにかかれています。
// FieldsPerRecord is the number of expected fields per record. // If FieldsPerRecord is positive, Read requires each record to // have the given number of fields. If FieldsPerRecord is 0, Read sets it to // the number of fields in the first record, so that future records must // have the same field count. If FieldsPerRecord is negative, no check is // made and records may have a variable number of fields. FieldsPerRecord int
サンプル
package csvop import ( "bytes" "encoding/csv" "fmt" ) // FieldsPerRecord は、csv.Reader.FieldsPerRecordのサンプルです。 // // csv.Reader.FieldsPerRecord は設定する値によって挙動が変わる。 // // - 「0より大きな正の値」を設定すると、その列数でない場合 *csv.ParseError が発生する // - 「0」を指定すると、最初の行の列数を基準として解析し、その列数でない場合 *csv.ParseError が発生する // - 「負の値」 を設定すると列が不揃いでもエラーにならない // // REFERENCES: // - https://pkg.go.dev/encoding/csv@go1.25.3#Reader.FieldsPerRecord func FieldsPerRecord() error { var ( data []byte ) data = fmt.Appendln(data, "hello,world") data = fmt.Appendln(data, "world,hello") data = fmt.Appendln(data, "HELLO,WORLD,999") // ここだけ列が不揃い // // FieldsPerRecordの値が「0より大きな正の値」 // (指定した列数で無い場合エラーとなる) // { var ( buf = bytes.NewBuffer(data) reader = csv.NewReader(buf) record []string err error ) reader.FieldsPerRecord = 2 for i := 0; ; i++ { if record, err = reader.Read(); err != nil { fmt.Printf("[0より大きな正の値] [%d] %T: %s\n", i, err, err) break } fmt.Printf("[0より大きな正の値] [%d] %v\n", i, record) } } // // FieldsPerRecordの値が「0」 // (先頭レコードの列数を基準として処理する) // { var ( buf = bytes.NewBuffer(data) reader = csv.NewReader(buf) record []string err error ) reader.FieldsPerRecord = 0 for i := 0; ; i++ { if record, err = reader.Read(); err != nil { fmt.Printf("[0 ] [%d] %T: %s\n", i, err, err) break } fmt.Printf("[0 ] [%d] %v\n", i, record) } } // // FieldsPerRecordの値が「負の値」 // (列数が不揃いでもエラーとならない) // { var ( buf = bytes.NewBuffer(data) reader = csv.NewReader(buf) record []string err error ) reader.FieldsPerRecord = -1 for i := 0; ; i++ { if record, err = reader.Read(); err != nil { fmt.Printf("[負の値 ] [%d] %T: %s\n", i, err, err) break } fmt.Printf("[負の値 ] [%d] %v\n", i, record) } } return nil }
実行
$ task
task: [run] ./try-golang -onetime
ENTER EXAMPLE NAME: csv_fields
[Name] "csv_fieldsperrecord"
[0より大きな正の値] [0] [hello world]
[0より大きな正の値] [1] [world hello]
[0より大きな正の値] [2] *csv.ParseError: record on line 3: wrong number of fields
[0 ] [0] [hello world]
[0 ] [1] [world hello]
[0 ] [2] *csv.ParseError: record on line 3: wrong number of fields
[負の値 ] [0] [hello world]
[負の値 ] [1] [world hello]
[負の値 ] [2] [HELLO WORLD 999]
[負の値 ] [3] *errors.errorString: EOF
[Elapsed] 352.396µs
参考情報
個人的Goのおすすめ書籍
個人的に読んでとても勉強になった書籍さんたちです。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。






