Commit 0580deaf authored by Rob Pike's avatar Rob Pike

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
parent 31f2503c
......@@ -4,9 +4,11 @@
/*
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.
Printing:
The verbs:
General:
......@@ -74,9 +76,23 @@
If an operand implements method String() string that method
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
// BUG(r): There is no format-driven scanning yet.
import (
"bytes"
......
......@@ -181,12 +181,32 @@ func (s *ss) token() 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
// 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(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)
n = s.doScan(a)
err = s.err
......@@ -194,13 +214,13 @@ func Scan(r io.Reader, a ...interface{}) (n int, err os.Error) {
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
// 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(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)
n = s.doScan(a)
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) {
testScan(t, Scan)
testScan(t, Fscan)
}
func TestScanln(t *testing.T) {
testScan(t, Scanln)
testScan(t, Fscanln)
}
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")
for _, test := range overflowTests {
r := strings.NewReader(test.text)
_, err := Scan(r, test.in)
_, err := Fscan(r, test.in)
if err == nil {
t.Errorf("expected overflow scanning %q", test.text)
continue
......@@ -162,7 +162,7 @@ func TestScanMultiple(t *testing.T) {
text := "1 2 3 x"
r := strings.NewReader(text)
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 {
t.Errorf("count error: expected 3: got %d", n)
}
......@@ -174,7 +174,7 @@ func TestScanMultiple(t *testing.T) {
func TestScanNotPointer(t *testing.T) {
r := strings.NewReader("1")
var a int
_, err := Scan(r, a)
_, err := Fscan(r, a)
if err == nil {
t.Error("expected error scanning non-pointer")
} else if strings.Index(err.String(), "pointer") < 0 {
......@@ -185,7 +185,7 @@ func TestScanNotPointer(t *testing.T) {
func TestScanlnNoNewline(t *testing.T) {
r := strings.NewReader("1 x\n")
var a int
_, err := Scanln(r, &a)
_, err := Fscanln(r, &a)
if err == nil {
t.Error("expected error scanning string missing newline")
} else if strings.Index(err.String(), "newline") < 0 {
......@@ -196,7 +196,7 @@ func TestScanlnNoNewline(t *testing.T) {
func TestScanlnWithMiddleNewline(t *testing.T) {
r := strings.NewReader("123\n456\n")
var a, b int
_, err := Scanln(r, &a, &b)
_, err := Fscanln(r, &a, &b)
if err == nil {
t.Error("expected error scanning string with extra newline")
} else if strings.Index(err.String(), "newline") < 0 {
......
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