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
Milestone

Comments

@astropanic
Copy link

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

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

@UserAB1236872
Copy link

Same behavior on go1.4 windows/amd64

@siritinga
Copy link

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 commented Jun 5, 2015

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

@robpike
Copy link
Contributor

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 as completed 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
@rsc rsc unassigned robpike Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants