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 %c skips a blank in Go1.5; not in Go1.3.3, nor in C #12275

Closed
strickyak opened this issue Aug 23, 2015 · 4 comments
Closed

fmt: Sscanf %c skips a blank in Go1.5; not in Go1.3.3, nor in C #12275

strickyak opened this issue Aug 23, 2015 · 4 comments

Comments

@strickyak
Copy link

What version of Go are you using (go version)?

I found this when upgrading from Go 1.3.3 to Go 1.5

What operating system and processor architecture are you using?

GOARCH="amd64"
GOOS="linux"

What did you do?

$ cat scango.go

package main

import "fmt"

func main() {
    var x int

    n, err := fmt.Sscanf("A", "%c", &x)
    println("n=", n, "x=", x, "err=", err)

    n, err = fmt.Sscanf(" A", "%c", &x)
    println("n=", n, "x=", x, "err=", err)

    n, err = fmt.Sscanf(" ", "%c", &x)
    println("n=", n, "x=", x, "err=", err)
}

What did you expect to see?

I expected what Go 1.3.3 did: it always gets the first character in the scanned string, either "A" or " ":
$ go run scango.go
n= 1 x= 65 err= (0x0,0x0)
n= 1 x= 32 err= (0x0,0x0)
n= 1 x= 32 err= (0x0,0x0)

That's also what my C compiler does
/* gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) */
$ cat scanc.c

#include <stdio.h>

main() {
  char x[33];
  int n = sscanf("A", "%c", x);
  printf("n=%d <%d>\n", n, *x);
  n = sscanf(" A", "%c", x);
  printf("n=%d <%d>\n", n, *x);
  n = sscanf(" ", "%c", x);
  printf("n=%d <%d>\n", n, *x);
}

$ gcc scanc.c
$ ./a.out
n=1 <65>
n=1 <32>
n=1 <32>

What did you see instead?

Under Go 1.5, it skips the blank, and advances to the "A" (in the second clause) or EOF (in the third clause):
$ go run scango.go
n= 1 x= 65 err= (0x0,0x0)
n= 1 x= 65 err= (0x0,0x0)
n= 0 x= 65 err= (0x7f555757b028,0xc82000a1d0)

@mikioh mikioh changed the title Sscanf %c skips a blank in Go1.5; not in Go1.3.3, nor in C fmt: Sscanf %c skips a blank in Go1.5; not in Go1.3.3, nor in C Aug 23, 2015
@mikioh
Copy link
Contributor

mikioh commented Aug 23, 2015

/CC @robpike

@robpike
Copy link
Contributor

robpike commented Aug 23, 2015

1.4 also gets a space. Arguably, it's doing what the docs say, but this new behavior, a consequence of a major internal restructuring, is clearly a change in behavior. Should perhaps be fixed. I wish instead we could just tell everyone not to use fmt.Scan*. I wish they had never been written.

@robpike robpike self-assigned this Aug 23, 2015
@robpike robpike added this to the Go1.6Early milestone Aug 23, 2015
@gopherbot
Copy link

CL https://golang.org/cl/13821 mentions this issue.

strickyak added a commit to strickyak/aphid that referenced this issue Sep 2, 2015
@adg adg modified the milestones: Go1.5.1, Go1.6Early Sep 8, 2015
@gopherbot
Copy link

CL https://golang.org/cl/14395 mentions this issue.

robpike added a commit that referenced this issue Sep 8, 2015
…kip spaces at %c

In short, %c should just give you the next rune, period.
Apparently this is the design. I use the term loosely.

Fixes #12275

Change-Id: I6f30bed442c0e88eac2244d465c7d151b29cf393
Reviewed-on: https://go-review.googlesource.com/13821
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-on: https://go-review.googlesource.com/14395
@golang golang locked and limited conversation to collaborators Sep 8, 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

5 participants