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

fmt: Sscanf handles spaces and \n inconsistently #8515

gopherbot opened this issue Aug 12, 2014 · 2 comments

fmt: Sscanf handles spaces and \n inconsistently #8515

gopherbot opened this issue Aug 12, 2014 · 2 comments


Copy link

@gopherbot gopherbot commented Aug 12, 2014


What does 'go version' print?
go version go1.3 linux/amd64

What steps reproduce the problem?
If possible, include a link to a program on


Try any of these examples with var x, y int
1. n, err = fmt.Sscanf("7 8", "%d %d", &x, &y)
2. n, err = fmt.Sscanf("7\n8", "%d %d", &x, &y)
3. n, err = fmt.Sscanf("7 8", "%d%d", &x, &y)
4. n, err = fmt.Sscanf("7\n8", "%d%d", &x, &y)
5. n, err = fmt.Sscanf("7\n\n8", "%d\n\n%d", &x, &y)

What happened?
The results are, respectively:
1. n=2
2. n=2
3. n=2
4. n=1
5. n=1

What should have happened instead?
If I am to believe the documentation for fmt, something like:
1. n=2
2. n=1
3. n=1
4. n=1
5. n=2

Please provide any additional information below.

See also issue #8236 for a related error.

Case (1) is as expected. All the other examples give surprising results, either
contradicting other examples or directly contradicting the docs.

The docs says "Scanf, Fscanf and Sscanf require newlines in the input to match
newlines in the format". Case (2) contradicts that, since apparently newlines in
the input can instead match a variety of kinds of space in the format.

The docs says "When scanning with a format, all non-empty runs of space characters
(except newline) are equivalent to a single space in both the format and the input. With
that proviso, text in the format string must match the input text;" Case (3)
contradicts that, since apparently certain spaces in the input don't have to match
anything in the format.

Case (4) is similar to case (3), but gives different results (arguably following the
docs this time).

Case (5) is just crazy talk, since the format matches the input perfectly.

Some of the problem seems to stem from 
fmt/scan.go:1075 func (s *ss) advance(format string) (i int)
which seems to treaty *any* sequence of spaces (including newlines) in the format string
as being equivalent to a single space, directly contradicting the docs for Sscanf and
friends. It also mishandles the case of "\r\n" in the input because, around
line 1096 it directly checks for '\n' without bothering to check for '\r' too. And all
of that code completely ignores ss.nlIsSpace, but then after the first input space it
invokes skipSpace which has yet different behavior.

Compounding those problems, in
fmt/scan.go:651 func (s *ss) scanInt(verb rune, bitSize int) int64
and many similar functions, skipSpace() is called, though the docs mention nothing about
skipping leading spaces. I think this one is just a documentation bug: classic C scanf
ignores leading spaces for most verbs, and apparently fmt/scan does too but does not
document that behavior and actually repeatedly implies the opposite.
Copy link

@ianlancetaylor ianlancetaylor commented Aug 12, 2014

Comment 1:

Labels changed: added repo-main, release-none.

@gopherbot gopherbot added new labels Aug 12, 2014
@bradfitz bradfitz removed the new label Dec 18, 2014
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc removed release-none labels Apr 10, 2015
Copy link

@robpike robpike commented Jul 1, 2015

Duplicate of #8944.

@robpike robpike closed this Jul 1, 2015
@golang golang locked and limited conversation to collaborators Jul 1, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.