Home > front end >  escape character got lost when reading buffer with csv reader
escape character got lost when reading buffer with csv reader

Time:10-19

I have a string "\"{1,2}\"\n", which contains escape char \" and \n.

I tried to converted into an array of bytes, and read this array back to string using a csv reader. However, I notice that these escape chars are eliminated from the read-back string. Code is here.

package main

import (
    "fmt"
    "bytes"
    "encoding/csv"
    
)

func main() {
    var buf bytes.Buffer
    data := "\"{1,2}\"\n"
    buf.WriteString(data)
    fmt.Println(buf) //{[34 123 49 44 50 125 34 10] 0 0}
    
    input_arr := []byte{34,123,49,44,50,125,34,10}
    var newbuf bytes.Buffer
    newbuf.Write(input_arr)
    csvReader := csv.NewReader(&newbuf)
    news, err := csvReader.Read()
    
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(news[0]) // [{1,2}]

}

I wonder how can I still keep these escape chars in my read-back string. I.e. news=="\"{1,2}\"\n"

CodePudding user response:

data is initialized with an interpreted string literal. The sequence \" denotes a single double quote character ", the backslash only appears in the source code but not in the string value. The compiler "eliminates" it when the string literal is interpreted.

If you want the backslash chars to be part of the string's value, use a raw string literal:

data := `\"{1,2}\"\n`
fmt.Println(data)

This will output:

\"{1,2}\"\n

Or alternatively keep using interpreted string literal and add a \\ sequence for a single backslash in the string value:

data := "\\\"{1,2}\\\"\\n"
fmt.Println(data)

This outputs the same.

If your goal is to add double quotes to the CSV column value, you have to use CSV escaping (quoted fields): that is, you have to put the cell into double quotes, and use 2 double quotes for a single double quote:

data := `"""{1,2}"""
`

csvReader := csv.NewReader(strings.NewReader(data))
news, err := csvReader.Read()

if err != nil {
    fmt.Println(err)
}
fmt.Println(news[0])

This will output (try it on the Go Playground):

"{1,2}"

This is documented in the package doc of encoding/csv:

Fields which start and stop with the quote character " are called quoted-fields. The beginning and ending quote are not part of the field.

The source:

normal string,"quoted-field"

results in the fields

{`normal string`, `quoted-field`}

Within a quoted-field a quote character followed by a second quote character is considered a single quote.

"the ""word"" is true","a ""quoted-field"""

results in

{`the "word" is true`, `a "quoted-field"`}
  • Related