read from Stdin

2,818 views
Skip to first unread message

Mehul Choube

unread,
Apr 26, 2012, 12:07:24 AM4/26/12
to golang-nuts
Hi,

I am trying to read input from Stdin but it is failing with 'Scan:
expected newline' error.

source code:

======= readFromStdin.go - start =======

package main

import (
"bufio"
"fmt"
"os"
)

var Stdin *bufio.Reader

func main() {
var i int

//fmt.Fscanf(Stdin, "%d", &i)

for {
_, err := fmt.Fscanln(Stdin, &i)
if err != nil {
fmt.Println(err)
break
}

fmt.Printf("You have entered %d.\n", i)
}
}

func init() {
Stdin = bufio.NewReader(os.Stdin)
}

======= readFromStdin.go - end =======

build command: 6g readFromStdin.go && 6l -o readFromStdin
readFromStdin.6

execution:

======= execution - start =======

mchoube@D-037652B:~/my_space/try/prac/go$ cat input.txt | ./
readFromStdin | more
You have entered 1415926.
You have entered 5358979.
You have entered 3238462.
You have entered 6433832.
You have entered 7950288.
You have entered 4197169.
You have entered 3993751.
Scan: expected newline

======= execution - end =======

input file:

======= input.txt - start =======

mchoube@D-037652B:~/my_space/try/prac/go$ cat input.txt | more
1415926
5358979
3238462
6433832
7950288
4197169
3993751
0582097
4944592
3078164
0628620
8998628
...
...

======= input.txt - end =======

please let me know what is wrong with the code?

Also, as I am new to golang and coming from C/C++ background, is this
forum good place to ask for code reviews?



Thanks,
Mehul

Kyle Lemons

unread,
Apr 26, 2012, 1:19:06 AM4/26/12
to Mehul Choube, golang-nuts
I suspect you have a blank line at the end of the file.

Mehul Choube

unread,
Apr 26, 2012, 1:34:58 AM4/26/12
to golang-nuts
same error with or without blank line at the end of file.



Thanks,
Mehul

andrey mirtchovski

unread,
Apr 26, 2012, 1:36:46 AM4/26/12
to golang-nuts
let's see if this helps:

$ cat | ./t
0
You have entered 0.
01
You have entered 1.
012
You have entered 10.
0123
You have entered 83.
01234
You have entered 668.
012345
You have entered 5349.
0123456
You have entered 42798.
01234567
You have entered 342391.
012345678
Scan: expected newline

Kyle Lemons

unread,
Apr 26, 2012, 1:41:45 AM4/26/12
to andrey mirtchovski, golang-nuts
Oh, good catch!

Christoph Hack

unread,
Apr 26, 2012, 1:44:10 AM4/26/12
to golan...@googlegroups.com


On Thursday, April 26, 2012 7:34:58 AM UTC+2, Mehul Choube wrote:
same error with or without blank line at the end of file. 

That's not true. With a newline, you will get an "unexpected newline" error, without
you won't get that.

But you probably also want to handle the EOF (end of file) error separately, by
just stopping the loop instead of reporting the error. Something like that:

-christoph 

roger peppe

unread,
Apr 26, 2012, 5:14:47 AM4/26/12
to Mehul Choube, golang-nuts
On 26 April 2012 05:07, Mehul Choube <mch...@gmail.com> wrote:
>                _, err := fmt.Fscanln(Stdin, &i)

Andrey pointed out what was going on here, but to be
a little more explicit, here's what the documentation says
(from http://golang.org/pkg/fmt):

: The familiar base-setting prefixes 0 (octal) and 0x (hexadecimal) are
: accepted when scanning integers without a format or with the %v verb.

What's happening is the fmt is seeing the "0" prefix and
disallowing any digits outside the range [0-7].

Unfortunately there's no equivalent of Fscanln (e.g. Fscanfln) that
allows scanning decimal numbers only.

You could use bufio.ReadSlice to read lines explicitly and then use fmt.Sscanf.

Alternatively you could implement a type that implements decimal-only
scanning, and continue to use Fscanln, for instance:
http://play.golang.org/p/PjzywMIYzZ

(It seems a pity that when presented with EOF, fmt.Fscanln returns io.EOF but
fmt.Fscanf returns io.ErrUnexpectedEOF - hence the fact that the example above
prints "unexpected EOF" rather than just "EOF" at the end.

Kyle Lemons

unread,
Apr 26, 2012, 1:31:23 PM4/26/12
to roger peppe, Mehul Choube, golang-nuts
On Thu, Apr 26, 2012 at 2:14 AM, roger peppe <rogp...@gmail.com> wrote:
On 26 April 2012 05:07, Mehul Choube <mch...@gmail.com> wrote:
>                _, err := fmt.Fscanln(Stdin, &i)

Andrey pointed out what was going on here, but to be
a little more explicit, here's what the documentation says
(from http://golang.org/pkg/fmt):

: The familiar base-setting prefixes 0 (octal) and 0x (hexadecimal) are
: accepted when scanning integers without a format or with the %v verb.

What's happening is the fmt is seeing the "0" prefix and
disallowing any digits outside the range [0-7].

Unfortunately there's no equivalent of Fscanln (e.g. Fscanfln) that
allows scanning decimal numbers only.

wouldn't fmt.Fscanf(in, "%d\n", &i) work?

roger peppe

unread,
Apr 27, 2012, 5:21:21 AM4/27/12
to Kyle Lemons, Mehul Choube, golang-nuts
On 26 April 2012 18:31, Kyle Lemons <kev...@google.com> wrote:
> On Thu, Apr 26, 2012 at 2:14 AM, roger peppe <rogp...@gmail.com> wrote:
>>
>> On 26 April 2012 05:07, Mehul Choube <mch...@gmail.com> wrote:
>> >                _, err := fmt.Fscanln(Stdin, &i)
>>
>> Andrey pointed out what was going on here, but to be
>> a little more explicit, here's what the documentation says
>> (from http://golang.org/pkg/fmt):
>>
>> : The familiar base-setting prefixes 0 (octal) and 0x (hexadecimal) are
>> : accepted when scanning integers without a format or with the %v verb.
>>
>> What's happening is the fmt is seeing the "0" prefix and
>> disallowing any digits outside the range [0-7].
>>
>> Unfortunately there's no equivalent of Fscanln (e.g. Fscanfln) that
>> allows scanning decimal numbers only.
>
>
> wouldn't fmt.Fscanf(in, "%d\n", &i) work?

It's true that in the original case that might be fine.
But there's a significant difference between the two:
Fscanf used like that won't work well in interactive mode - it
reads again after finding the newline, so you won't
see a response until you have typed the *next* line.

I don't know if that's a bug or a feature, but it does
mean they aren't equivalent.

Here's a little demo of the difference between the two:

http://play.golang.org/p/plwBIIYiqG
Reply all
Reply to author
Forward
0 new messages