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: inconsistent handling of \r in Scanf #9459

Closed
astropanic opened this issue Dec 27, 2014 · 5 comments
Closed

fmt: inconsistent handling of \r in Scanf #9459

astropanic opened this issue Dec 27, 2014 · 5 comments
Assignees
Milestone

Comments

@astropanic
Copy link

@astropanic astropanic commented Dec 27, 2014

I got different fmt.Scanf behavior depending on the line endings style.

My go version is go1.3.3 darwin/amd64 on a Mac with OSX 10.10

To reproduce the problem, here is a short go program:

package main

import "fmt"

func main() {
    var steps, i int
    fmt.Scanf("%d", &steps)

    var a, b int
    for i = 0; i < steps; i++ {
        fmt.Scanf("%d", &a)
        fmt.Scanf("%d", &b)
        fmt.Println(a + b)
    }
}

And an input file

2
2 5
4           8

go run test.go < input

I expect to see regardless of the line endings been \r\n or \n:

7
12

But I see

2
7

when in the input file the line endings are \r\n .

If the line endings are \n it works fine.

@RealPadrone
Copy link

@RealPadrone RealPadrone commented Dec 27, 2014

Same behaviour with go version go1.2.1 linux/amd64 on Ubuntu 14.04.

@Zaerei
Copy link

@Zaerei Zaerei commented Dec 27, 2014

Same behavior on go1.4 windows/amd64

@siritinga
Copy link

@siritinga siritinga commented Dec 27, 2014

As I understand, you have to give the \n in the format string if a newline is expected. Then it will work regardless of the line ending.

From the fmt package documentation: Scanf, Fscanf and Sscanf require newlines in the input to match newlines in the format

However, I think the documentation is misleading: In all the scanning functions, a carriage return followed immediately by a newline is treated as a plain newline (\r\n means the same as \n).

Always, and then there is a bug, or only when the formatting string has a \n?

@mikioh mikioh changed the title weird fmt.Scanf behavior with non unix line endings fmt: vague Scanf behavior with line endings Dec 27, 2014
@robpike robpike changed the title fmt: vague Scanf behavior with line endings fmt: inconsistent handling of \r in Scanf Jan 6, 2015
@robpike robpike self-assigned this Jan 6, 2015
@rsc rsc added this to the Go1.5 milestone Apr 10, 2015
@robpike
Copy link
Contributor

@robpike robpike commented Jun 5, 2015

Working as intended, but the documentation needs to be improved.

@robpike
Copy link
Contributor

@robpike robpike commented Jun 15, 2015

There have been several fixes to fmt.Scanf in the recent flurry. Your example behaves consistently for me now if I rewrite it as follows, making sure the newlines appear in the format to match the input.

package main

import (
"fmt"
"strings"
)

func main() {
do("2\r\n2 5\r\n4 8\r\n")
do("2\n2 5\n4 8\n")
}

func do(s string) {
file := strings.NewReader(s)
var steps int
fmt.Fscanf(file, "%d\n", &steps)
fmt.Println("steps:", steps)

var a, b int
for i := 0; i < steps; i++ {
    a = -1
    b = -1
    n, err := fmt.Fscanf(file, "%d", &a)
    fmt.Println("first", n, err)
    n, err = fmt.Fscanf(file, "%d\n", &b)
    fmt.Println("second", n, err)
    fmt.Println(a, b, a+b)
}

}

@robpike robpike closed this Jun 15, 2015
travisby added a commit to travisby/go-redis-server that referenced this issue Mar 22, 2016
In go1.5 the Scanf parser was changed WRT to line feeds.

Newer versions of go would fail on every fmt.Sscanf function due to:

golang/go#9459
@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

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