Skip to content

Commit

Permalink
fmt: in Scanf, %c can scan a space, so don't skip spaces at %c
Browse files Browse the repository at this point in the history
In short, %c should just give you the next rune, period.
Apparently this is the design. I use the term loosely.

Fixes golang#12275

Change-Id: I6f30bed442c0e88eac2244d465c7d151b29cf393
Reviewed-on: https://go-review.googlesource.com/13821
Reviewed-by: Andrew Gerrand <[email protected]>
  • Loading branch information
robpike committed Aug 24, 2015
1 parent 47bdda6 commit b1eec18
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
13 changes: 9 additions & 4 deletions src/fmt/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ func Scanln(a ...interface{}) (n int, err error) {
// the format. It returns the number of items successfully scanned.
// If that is less than the number of arguments, err will report why.
// Newlines in the input must match newlines in the format.
// The one exception: the verb %c always scans the next rune in the
// input, even if it is a space (or tab etc.) or newline.
func Scanf(format string, a ...interface{}) (n int, err error) {
return Fscanf(os.Stdin, format, a...)
}
Expand Down Expand Up @@ -1164,15 +1166,18 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro
if !widPresent {
s.maxWid = hugeWid
}
s.SkipSpace()

c, w := utf8.DecodeRuneInString(format[i:])
i += w

if c != 'c' {
s.SkipSpace()
}
s.argLimit = s.limit
if f := s.count + s.maxWid; f < s.argLimit {
s.argLimit = f
}

c, w := utf8.DecodeRuneInString(format[i:])
i += w

if numProcessed >= len(a) { // out of operands
s.errorString("too few operands for format %" + format[i-w:])
break
Expand Down
11 changes: 7 additions & 4 deletions src/fmt/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,13 @@ var scanfTests = []ScanfTest{
{"%2s", "sssss", &xVal, Xs("ss")},

// Fixed bugs
{"%d\n", "27\n", &intVal, 27}, // ok
{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
{"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
{"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
{"%d\n", "27\n", &intVal, 27}, // ok
{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
{"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
{"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
{"%c", " ", &uintVal, uint(' ')}, // %c must accept a blank.
{"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space.
{"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space.
}

var overflowTests = []ScanTest{
Expand Down

0 comments on commit b1eec18

Please sign in to comment.