Why this example of fmt.Sscanf doesn't work?

904 views
Skip to first unread message

resal

unread,
Dec 25, 2014, 4:51:05 PM12/25/14
to golan...@googlegroups.com
Hi,

I have a well-formatted input string and decided to use fmt.Sscanf to parse it. Here is a simple example (play link: http://play.golang.org/p/WlMpKiMGIv):

package main

import "fmt"

func main() {
format := "%6s%5d"
//      "ssssssddddd"
line := "some      3"

var str string
var numb int64
n, err := fmt.Sscanf(line, format, &str, &numb)
fmt.Println(n, err)
fmt.Println(str, numb)
}

And the output is:

1 EOF
some 0

Can you please point out why this doesn't work? 

Thanks.





seppo...@gmail.com

unread,
Dec 25, 2014, 5:09:57 PM12/25/14
to golan...@googlegroups.com
Scanning a string is space delimited. (http://golang.org/pkg/fmt/ -> Scanning)

In your case you have 7 spaces before '3', instead the maximum expected 5.

seppo...@gmail.com

unread,
Dec 25, 2014, 5:13:37 PM12/25/14
to golan...@googlegroups.com
Small error.
6 Spaces before '3' and expected maximum of 4 spaces before it.
 

resal

unread,
Dec 25, 2014, 5:22:36 PM12/25/14
to golan...@googlegroups.com, seppo...@gmail.com

Hmm. So there must be space between the input arguments. I was under impression that when I specify "%6s" it would consume 6 characters and leaving the remaining 5 characters (4 spaces + '3') for "%5d". 

Then I guess I have to to slice the line and then parse the resulting fragments.

Thanks.

Karol Mieczysław Marcjan

unread,
Dec 25, 2014, 7:04:00 PM12/25/14
to golan...@googlegroups.com, seppo...@gmail.com
W dniu czwartek, 25 grudnia 2014 23:22:36 UTC+1 użytkownik resal napisał:

Hmm. So there must be space between the input arguments. I was under impression that when I specify "%6s" it would consume 6 characters and leaving the remaining 5 characters (4 spaces + '3') for "%5d". 

Then I guess I have to to slice the line and then parse the resulting fragments.

Thanks.

Is there a particularily good reason to use a string instead of an io.Reader? You wouldn't have this problem if you were doing using fmt.Fscan with separate format strings for each argument.

-- Karol Marcjan

Rob Pike

unread,
Dec 25, 2014, 7:05:38 PM12/25/14
to Karol Mieczysław Marcjan, golan...@googlegroups.com, seppo...@gmail.com
I think the behavior is a bug and have filed https://github.com/golang/go/issues/9444 to settle the matter.

That said, there are more efficient ways to split fixed-format text than to use fmt.Scan.

-rob


--
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.
For more options, visit https://groups.google.com/d/optout.

resal

unread,
Dec 25, 2014, 7:31:22 PM12/25/14
to golan...@googlegroups.com, karol....@gmail.com, seppo...@gmail.com
I see. Thanks for the explanation.

For now I'm slicing these fixed-format lines to extract 12 fields (example code below). I'd appreciate it if you could give me pointers/sample code for better (e.g. more idiomatic or more efficient) ways to do the same task.


str := strings.TrimSpace(line[0:6])
numb, err :=  strconv.ParseInt(strings.TrimSpace(line[6:11]), 10, 64)
...

Thanks.

Rob Pike

unread,
Dec 25, 2014, 8:34:45 PM12/25/14
to resal, golan...@googlegroups.com, Karol Marcjan, seppo...@gmail.com
I would use that approach myself. Don't forget to check for errors.

-rob

Reply all
Reply to author
Forward
0 new messages