fmt.Sscanf strange behaviour

436 views
Skip to first unread message

Victor Giordano

unread,
Jan 25, 2022, 2:35:01 PM1/25/22
to golang-nuts
Hi all! I'm dealing with some multi valued column in postgres, and i have stomp into a bizzare behavoir in `fmt.Sscanf`

Please take a look at the following snippet, i also leave my question within the code and this link to the playground so you can actually try it and see with you own eyes.

```
package main

import "fmt"

func main() {
        var a int
        var b string
        input := "(1,beto)" // doesn't like the parenthesis

        _, err := fmt.Sscanf(input, "(%d,%s)", &a, &b)
        if err != nil {
                fmt.Println(err)
        } else {
                fmt.Println(a, b)
        }

        input = "1,beto" // this works
        _, err = fmt.Sscanf(input, "%d,%s", &a, &b)
        if err != nil {
                fmt.Println(err)
        } else {
                fmt.Println(a, b)
        }

        input = "beto,1" // doesn't like an string at first place, ¿¿WHAT i do?!?!
        _, err = fmt.Sscanf(input, "%s,%d", &b, &a)
        if err != nil {
                fmt.Println(err)
        } else {
                fmt.Println(a, b)
        }
}
```

I saw this ticket i'm wondering about how realiable is the Sscanf function indeed, as i saw that you guys having problems too.

Thanks for reading me!

V

Ian Lance Taylor

unread,
Jan 25, 2022, 2:42:27 PM1/25/22
to Victor Giordano, golang-nuts
Using %s in fmt.Sscanf will read all characters up to a space or
newline. This is documented at https://pkg.go.dev/fmt which says
"Input processed by verbs is implicitly space-delimited: the
implementation of every verb except %c starts by discarding leading
spaces from the remaining input, and the %s verb (and %v reading into
a string) stops consuming input at the first space or newline
character."

Basically fmt.Sscanf is not the right tool for the problem you are
trying to solve.

Ian

Victor Giordano

unread,
Jan 25, 2022, 3:46:11 PM1/25/22
to Ian Lance Taylor, golang-nuts
Thanks Ian, I will take your advice and use another approach, I regret this cuz it would be nice to have something already working. 

Without any intent to offense or say something hard, as a client of the library it kind looks quite buggy, the parenthesis are still an issue disregarding that the values are actually space-delimited. The error messages clearly are an invitation to see the source for deeper understanding rather than given any clues.

Greetings

V


--
V

Ian Lance Taylor

unread,
Jan 25, 2022, 4:06:03 PM1/25/22
to Victor Giordano, golang-nuts
On Tue, Jan 25, 2022 at 12:45 PM Victor Giordano <vituc...@gmail.com> wrote:
>
> Thanks Ian, I will take your advice and use another approach, I regret this cuz it would be nice to have something already working.
>
> Without any intent to offense or say something hard, as a client of the library it kind looks quite buggy, the parenthesis are still an issue disregarding that the values are actually space-delimited. The error messages clearly are an invitation to see the source for deeper understanding rather than given any clues.

Your newer example is still working as documented. The %s swallows
everything up to the space, including the right parenthesis. Then
there is nothing to match the right parenthesis in the format string.

This behavior dates back to the C function sscanf that the Go code is
based on. The %s code can be useful for space-separated fields, but
is not very useful for anything else.

Ian

Victor Giordano

unread,
Jan 25, 2022, 6:00:41 PM1/25/22
to Ian Lance Taylor, golang-nuts
Thanks for the insight again. It is appreciated.
Till next time.

V
--
V

Roland Müller

unread,
Jan 25, 2022, 11:51:04 PM1/25/22
to golang-nuts
The tool you are looking for is most probably the regex module:

https://pkg.go.dev/regexp

BR
Roland
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAPUu9sv-bF7KM_xTdPCP9SP%2BuCarz04DvjKGBuvS92sYV%2BP4iQ%40mail.gmail.com.
>

Brian Candler

unread,
Jan 26, 2022, 4:01:47 AM1/26/22
to golang-nuts
On Wednesday, 26 January 2022 at 04:51:04 UTC rol...@gmail.com wrote:
The tool you are looking for is most probably the regex module:

https://pkg.go.dev/regexp

"Then you have two problems" :-)  But it could be reasonable here if the format is fixed.

If this is a true multi-valued column in postgres, such as an array type, then I would be trying to get the postgres API to return this to me in a structured way, e.g. see here.

If this is just a string field which happens to contain the text "(foo,bar)" then this is a custom serialization of your data, and you'll have to parse this custom format yourself.  I'd be thinking "what should happen if the parentheses are missing? How does this format represent a value which contains a comma or contains a parenthesis?"
Reply all
Reply to author
Forward
0 new messages