Read until EOF

3,265 views
Skip to first unread message

PJOX

unread,
May 15, 2011, 11:47:05 PM5/15/11
to golan...@googlegroups.com
Hi,

I'm new to the Go programming language and I've been trying to make simple programs in Go, but I haven't figured out how to read an input until EOF.

I'm trying to find a way to do this like I do it in C/C++:

while (scanf("%s", &s)) { }

But i seems that in Go 

for fmt.Scanf("%s", &s) { }

is not permitted.

Any suggestions?

Ostsol

unread,
May 16, 2011, 12:04:46 AM5/16/11
to golang-nuts
On May 15, 9:47 pm, PJOX <ortizpe...@gmail.com> wrote:
> for fmt.Scanf("%s", &s) { }
>
> is not permitted.

The problem here is that fmt.Scanf returns two values: the number of
items scanned an an error. A 'for' statement used in that form
requires a boolean expression. Accounting for that, there is no
problem. For example:

func main() {
var str string
for {
n, err := fmt.Scanf("%s", &str)
if n == 0 || err != nil { break }

// do stuff
}
}

Type some words, press enter, and press enter again. The loop will
exit. Or read using fmt.Fscanf from a file or byte.Buffer containing
a few words. The loop will exit at the end of the file/buffer.

-Daniel

PJOX

unread,
May 16, 2011, 1:59:28 AM5/16/11
to golan...@googlegroups.com
Thank you! it worked! :)

PJOX

unread,
May 16, 2011, 2:47:26 PM5/16/11
to golan...@googlegroups.com
BTW, is there a function in Go that works like the std::cin of C++?

For example, if I have an input like this:
1
2
3
4

5 6
7 8 9 10

And a program like this:

int d = 0;
for (int i = 0; i < 10; i++) {
   std::cin >> d;
   std::cout << d << endl;
}


The std::cin will ignore the format of the input and it will assign the next value to d. Is there a way to do this in Go?

John Asmuth

unread,
May 16, 2011, 3:08:11 PM5/16/11
to golan...@googlegroups.com
You can use fmt.Scanf("%v", &d) - it will use reflect to infer d's type and treat the input as an integer.

PJOX

unread,
May 16, 2011, 3:15:55 PM5/16/11
to golan...@googlegroups.com
It doesn't work, I need it to ignore the line between the 4 and 5. I just need a way to read the next integer/float/string... on the input.

John Asmuth

unread,
May 16, 2011, 3:19:29 PM5/16/11
to golan...@googlegroups.com
You might have to write some of your own code, then.

I don't think that there exists any "func GetNextThing(io.Reader, interface{})" function in the core library, right now.

Steven

unread,
May 16, 2011, 3:23:00 PM5/16/11
to golan...@googlegroups.com
On Mon, May 16, 2011 at 3:15 PM, PJOX <ortiz...@gmail.com> wrote:
It doesn't work, I need it to ignore the line between the 4 and 5. I just need a way to read the next integer/float/string... on the input.

package main

import "fmt"

func main() {
var d int
for i := 0; i < 10; {
n, _ := fmt.Scan(&d)
if n == 1 { // an integer was found
fmt.Println(d)
i++
}
}
}

This will successfully read your input. It ignores any lines that don't have integers on them.

John Asmuth

unread,
May 16, 2011, 3:31:04 PM5/16/11
to golan...@googlegroups.com
Looks like I was wrong - the GetNextThing(io.Reader, interface{}) function is fmt.Fscan.
Message has been deleted

PJOX

unread,
May 16, 2011, 5:02:59 PM5/16/11
to golan...@googlegroups.com
Thank you! it worked!

PJOX

unread,
May 16, 2011, 5:05:39 PM5/16/11
to golan...@googlegroups.com
could you give me an example of how to use fmt.Fscan to make it work like the std::cin in the example I gave?

Steven

unread,
May 16, 2011, 7:26:34 PM5/16/11
to golan...@googlegroups.com
On Mon, May 16, 2011 at 5:05 PM, PJOX <ortiz...@gmail.com> wrote:
could you give me an example of how to use fmt.Fscan to make it work like the std::cin in the example I gave?

The difference isn't between fmt.Fscan and fmt.Scan, but instead between fmt.Scan and fmt.Scanf. fmt.Fscan* is used by fmt.Scan*, so you won't get any difference between them.

This code will work:

package main

import "fmt"

func main() {
        var d int
        for i := 0; i < 10; i++ {
                fmt.Scan(&d)
                fmt.Println(d)
        }
}


Whereas this code doesn't, and needs extra error handling:

package main

import "fmt"

func main() {
        var d int
        for i := 0; i < 10; i++ {
                fmt.Scanf("%d", &d)
                fmt.Println(d)
        }
}

My original example was written with fmt.Scanf, and then I switched it to fmt.Scan, not realizing this made the extra work unnecessary. Note that you should always handle errors on input anyway, this is just a simple case.

Steven

unread,
May 16, 2011, 7:52:24 PM5/16/11
to golan...@googlegroups.com
Oh, I've been meaning to ask, why don't the scanning functions in fmt ever return os.EOF? Its just a tad frustrating that you can't tell whether you've run out of input or not.

Rob 'Commander' Pike

unread,
May 16, 2011, 8:03:28 PM5/16/11
to Steven, golan...@googlegroups.com

On May 16, 2011, at 4:52 PM, Steven wrote:

> Oh, I've been meaning to ask, why don't the scanning functions in fmt ever return os.EOF? Its just a tad frustrating that you can't tell whether you've run out of input or not.

They return an error stating what they were looking for when they ran out of input. Why do you need os.EOF specifically?

-rob

PJOX

unread,
May 16, 2011, 9:09:52 PM5/16/11
to golan...@googlegroups.com
Thank you, it worked.

PJOX

unread,
May 16, 2011, 9:11:28 PM5/16/11
to golan...@googlegroups.com
this may work:
Reply all
Reply to author
Forward
0 new messages