mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
fmt.Scan: add Fscan and Fscanln and make Scan and Scanln
read from standard input. Add description of scanning to the package comment. R=rsc CC=golang-dev https://golang.org/cl/1390041
This commit is contained in:
parent
31f2503cde
commit
0580deafaf
3 changed files with 48 additions and 12 deletions
|
|
@ -4,9 +4,11 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package fmt implements formatted I/O with functions analogous
|
Package fmt implements formatted I/O with functions analogous
|
||||||
to C's printf. The format 'verbs' are derived from C's but
|
to C's printf and scanf. The format 'verbs' are derived from C's but
|
||||||
are simpler.
|
are simpler.
|
||||||
|
|
||||||
|
Printing:
|
||||||
|
|
||||||
The verbs:
|
The verbs:
|
||||||
|
|
||||||
General:
|
General:
|
||||||
|
|
@ -74,9 +76,23 @@
|
||||||
|
|
||||||
If an operand implements method String() string that method
|
If an operand implements method String() string that method
|
||||||
will be used for %v, %s, or Print etc.
|
will be used for %v, %s, or Print etc.
|
||||||
|
|
||||||
|
Scanning:
|
||||||
|
|
||||||
|
An analogous set of functions scans formatted text to yield
|
||||||
|
values. Scan and Scanln read from os.Stdin; Fscan and Fscanln
|
||||||
|
read from a specified os.Reader. By default, tokens are
|
||||||
|
separated by spaces. Fscanln and Scanln stop scanning at a
|
||||||
|
newline and require that the items be followed by one; the
|
||||||
|
other routines treat newlines as spaces.
|
||||||
|
|
||||||
|
If an operand implements method Scan() (that is, it implements
|
||||||
|
the Scanner interface) that method will be used to scan the
|
||||||
|
text for that operand.
|
||||||
*/
|
*/
|
||||||
package fmt
|
package fmt
|
||||||
|
|
||||||
|
// BUG(r): There is no format-driven scanning yet.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
|
||||||
|
|
@ -181,12 +181,32 @@ func (s *ss) token() string {
|
||||||
return s.buf.String()
|
return s.buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan parses text read from r, storing successive space-separated values
|
// Scan parses text read from standard input, storing successive
|
||||||
|
// space-separated values into successive arguments. Newlines count as
|
||||||
|
// space. Each argument must be a pointer to a basic type or an
|
||||||
|
// implementation of the Scanner interface. It returns the number of items
|
||||||
|
// successfully parsed. If that is less than the number of arguments, err
|
||||||
|
// will report why.
|
||||||
|
func Scan(a ...interface{}) (n int, err os.Error) {
|
||||||
|
return Fscan(os.Stdin, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fscanln parses text read from standard input, storing successive
|
||||||
|
// space-separated values into successive arguments. Scanning stops at a
|
||||||
|
// newline and after the final item there must be a newline or EOF. Each
|
||||||
|
// argument must be a pointer to a basic type or an implementation of the
|
||||||
|
// Scanner interface. It returns the number of items successfully parsed.
|
||||||
|
// If that is less than the number of arguments, err will report why.
|
||||||
|
func Scanln(a ...interface{}) (n int, err os.Error) {
|
||||||
|
return Fscanln(os.Stdin, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fscan parses text read from r, storing successive space-separated values
|
||||||
// into successive arguments. Newlines count as space. Each argument must
|
// into successive arguments. Newlines count as space. Each argument must
|
||||||
// be a pointer to a basic type or an implementation of the Scanner
|
// be a pointer to a basic type or an implementation of the Scanner
|
||||||
// interface. It returns the number of items successfully parsed. If that
|
// interface. It returns the number of items successfully parsed. If that
|
||||||
// is less than the number of arguments, err will report why.
|
// is less than the number of arguments, err will report why.
|
||||||
func Scan(r io.Reader, a ...interface{}) (n int, err os.Error) {
|
func Fscan(r io.Reader, a ...interface{}) (n int, err os.Error) {
|
||||||
s := newScanState(r, true)
|
s := newScanState(r, true)
|
||||||
n = s.doScan(a)
|
n = s.doScan(a)
|
||||||
err = s.err
|
err = s.err
|
||||||
|
|
@ -194,13 +214,13 @@ func Scan(r io.Reader, a ...interface{}) (n int, err os.Error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scanln parses text read from r, storing successive space-separated values
|
// Fscanln parses text read from r, storing successive space-separated values
|
||||||
// into successive arguments. Scanning stops at a newline and after the
|
// into successive arguments. Scanning stops at a newline and after the
|
||||||
// final item there must be a newline or EOF. Each argument must be a
|
// final item there must be a newline or EOF. Each argument must be a
|
||||||
// pointer to a basic type or an implementation of the Scanner interface. It
|
// pointer to a basic type or an implementation of the Scanner interface. It
|
||||||
// returns the number of items successfully parsed. If that is less than the
|
// returns the number of items successfully parsed. If that is less than the
|
||||||
// number of arguments, err will report why.
|
// number of arguments, err will report why.
|
||||||
func Scanln(r io.Reader, a ...interface{}) (n int, err os.Error) {
|
func Fscanln(r io.Reader, a ...interface{}) (n int, err os.Error) {
|
||||||
s := newScanState(r, false)
|
s := newScanState(r, false)
|
||||||
n = s.doScan(a)
|
n = s.doScan(a)
|
||||||
err = s.err
|
err = s.err
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,11 @@ func testScan(t *testing.T, scan func(r io.Reader, a ...interface{}) (int, os.Er
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScan(t *testing.T) {
|
func TestScan(t *testing.T) {
|
||||||
testScan(t, Scan)
|
testScan(t, Fscan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScanln(t *testing.T) {
|
func TestScanln(t *testing.T) {
|
||||||
testScan(t, Scanln)
|
testScan(t, Fscanln)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScanOverflow(t *testing.T) {
|
func TestScanOverflow(t *testing.T) {
|
||||||
|
|
@ -147,7 +147,7 @@ func TestScanOverflow(t *testing.T) {
|
||||||
re := testing.MustCompile("overflow|too large|out of range|not representable")
|
re := testing.MustCompile("overflow|too large|out of range|not representable")
|
||||||
for _, test := range overflowTests {
|
for _, test := range overflowTests {
|
||||||
r := strings.NewReader(test.text)
|
r := strings.NewReader(test.text)
|
||||||
_, err := Scan(r, test.in)
|
_, err := Fscan(r, test.in)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected overflow scanning %q", test.text)
|
t.Errorf("expected overflow scanning %q", test.text)
|
||||||
continue
|
continue
|
||||||
|
|
@ -162,7 +162,7 @@ func TestScanMultiple(t *testing.T) {
|
||||||
text := "1 2 3 x"
|
text := "1 2 3 x"
|
||||||
r := strings.NewReader(text)
|
r := strings.NewReader(text)
|
||||||
var a, b, c, d int
|
var a, b, c, d int
|
||||||
n, err := Scan(r, &a, &b, &c, &d)
|
n, err := Fscan(r, &a, &b, &c, &d)
|
||||||
if n != 3 {
|
if n != 3 {
|
||||||
t.Errorf("count error: expected 3: got %d", n)
|
t.Errorf("count error: expected 3: got %d", n)
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +174,7 @@ func TestScanMultiple(t *testing.T) {
|
||||||
func TestScanNotPointer(t *testing.T) {
|
func TestScanNotPointer(t *testing.T) {
|
||||||
r := strings.NewReader("1")
|
r := strings.NewReader("1")
|
||||||
var a int
|
var a int
|
||||||
_, err := Scan(r, a)
|
_, err := Fscan(r, a)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error scanning non-pointer")
|
t.Error("expected error scanning non-pointer")
|
||||||
} else if strings.Index(err.String(), "pointer") < 0 {
|
} else if strings.Index(err.String(), "pointer") < 0 {
|
||||||
|
|
@ -185,7 +185,7 @@ func TestScanNotPointer(t *testing.T) {
|
||||||
func TestScanlnNoNewline(t *testing.T) {
|
func TestScanlnNoNewline(t *testing.T) {
|
||||||
r := strings.NewReader("1 x\n")
|
r := strings.NewReader("1 x\n")
|
||||||
var a int
|
var a int
|
||||||
_, err := Scanln(r, &a)
|
_, err := Fscanln(r, &a)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error scanning string missing newline")
|
t.Error("expected error scanning string missing newline")
|
||||||
} else if strings.Index(err.String(), "newline") < 0 {
|
} else if strings.Index(err.String(), "newline") < 0 {
|
||||||
|
|
@ -196,7 +196,7 @@ func TestScanlnNoNewline(t *testing.T) {
|
||||||
func TestScanlnWithMiddleNewline(t *testing.T) {
|
func TestScanlnWithMiddleNewline(t *testing.T) {
|
||||||
r := strings.NewReader("123\n456\n")
|
r := strings.NewReader("123\n456\n")
|
||||||
var a, b int
|
var a, b int
|
||||||
_, err := Scanln(r, &a, &b)
|
_, err := Fscanln(r, &a, &b)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error scanning string with extra newline")
|
t.Error("expected error scanning string with extra newline")
|
||||||
} else if strings.Index(err.String(), "newline") < 0 {
|
} else if strings.Index(err.String(), "newline") < 0 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue