Commit a1fe3b50 authored by Rob Pike's avatar Rob Pike

fmt: scanning widths apply after leading spaces

When scanning with a width, as in %5s, C skips leading spaces
brefore counting the 5 characters. We should do the same.

Reword the documentation about widths to make this clear.

Fixes #9444

Change-Id: I443a6441adcf1c834057ef3977f9116a987a79cd
Reviewed-on: https://go-review.googlesource.com/10997Reviewed-by: 's avatarAndrew Gerrand <adg@golang.org>
parent ff8f3f0f
...@@ -271,13 +271,18 @@ ...@@ -271,13 +271,18 @@
Flags # and + are not implemented. Flags # and + are not implemented.
The familiar base-setting prefixes 0 (octal) and 0x The familiar base-setting prefixes 0 (octal) and 0x
(hexadecimal) are accepted when scanning integers without a (hexadecimal) are accepted when scanning integers without
format or with the %v verb. a format or with the %v verb.
Width is interpreted in the input text (%5s means at most Width is interpreted in the input text but there is no
five runes of input will be read to scan a string) but there syntax for scanning with a precision (no %5.2f, just %5f).
is no syntax for scanning with a precision (no %5.2f, just If width is provided, it applies after leading spaces are
%5f). trimmed and specifies the maximum number of runes to read
to satisfy the verb. For example,
Sscanf(" 1234567 ", "%5s%d", &s, &i)
will set s to "12345" and i to 67 while
Sscanf(" 12 34 567 ", "%5s%d", &s, &i)
will set s to "12" and i to 34.
In all the scanning functions, a carriage return followed In all the scanning functions, a carriage return followed
immediately by a newline is treated as a plain newline immediately by a newline is treated as a plain newline
......
...@@ -1165,6 +1165,7 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro ...@@ -1165,6 +1165,7 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro
if !widPresent { if !widPresent {
s.maxWid = hugeWid s.maxWid = hugeWid
} }
s.SkipSpace()
s.argLimit = s.limit s.argLimit = s.limit
if f := s.count + s.maxWid; f < s.argLimit { if f := s.count + s.maxWid; f < s.argLimit {
s.argLimit = f s.argLimit = f
......
...@@ -340,6 +340,8 @@ var multiTests = []ScanfMultiTest{ ...@@ -340,6 +340,8 @@ var multiTests = []ScanfMultiTest{
{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""}, {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
{"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""},
{"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""},
// Custom scanners. // Custom scanners.
{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment