How can I read from standard input in the console?

Go

Go Problem Overview


I would like to read standard input from the command line, but my attempts have ended with the program exiting before I'm prompted for input. I'm looking for the equivalent of Console.ReadLine() in C#.

This is what I currently have:

package main

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

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    text, _ := reader.ReadString('\n')
    fmt.Println(text)

    fmt.Println("Enter text: ")
    text2 := ""
    fmt.Scanln(text2)
    fmt.Println(text2)

    ln := ""
    fmt.Sscanln("%v", ln)
    fmt.Println(ln)
}

Go Solutions


Solution 1 - Go

I'm not sure what's wrong with the block

reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)

As it works on my machine. However, for the next block you need a pointer to the variables you're assigning the input to. Try replacing fmt.Scanln(text2) with fmt.Scanln(&text2). Don't use Sscanln, because it parses a string already in memory instead of from stdin. If you want to do something like what you were trying to do, replace it with fmt.Scanf("%s", &ln)

If this still doesn't work, your culprit might be some weird system settings or a buggy IDE.

Solution 2 - Go

You can as well try:

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if scanner.Err() != nil {
    // Handle error.
}

Solution 3 - Go

I think a more standard way to do this would be:

package main

import "fmt"

func main() {
    fmt.Print("Enter text: ")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}

Take a look at the scan godoc: http://godoc.org/fmt#Scan

> Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space. > > Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.

Solution 4 - Go

Always try to use the bufio.NewScanner for collecting input from the console. As others mentioned, there are multiple ways to do the job, but Scanner is originally intended to do the job. Dave Cheney explains why you should use Scanner instead of bufio.Reader's ReadLine.

https://twitter.com/davecheney/status/604837853344989184?lang=en

Here is the code snippet answer for your question

package main

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

/*
 Three ways of taking input
   1. fmt.Scanln(&input)
   2. reader.ReadString()
   3. scanner.Scan()

   Here we recommend using bufio.NewScanner
*/

func main() {
    // To create dynamic array
    arr := make([]string, 0)
    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("Enter Text: ")
        // Scans a line from Stdin(Console)
        scanner.Scan()
        // Holds the string that scanned
        text := scanner.Text()
        if len(text) != 0 {
            fmt.Println(text)
            arr = append(arr, text)
        } else {
            break
        }

    }
    // Use collected inputs
    fmt.Println(arr)
}

If you don't want to programmatically collect the inputs, just add these lines

   scanner := bufio.NewScanner(os.Stdin)
   scanner.Scan()
   text := scanner.Text()
   fmt.Println(text)

The output of above program will be:

Enter Text: Bob
Bob
Enter Text: Alice
Alice
Enter Text:
[Bob Alice]

The above program collects the user input and saves them to an array. We can also break that flow with a special character. Scanner provides API for advanced usage like splitting using a custom function, etc., scanning different types of I/O streams (standard Stdin, String), etc.

Edit: The tweet linked in original post is not accesible. But, one can find official reference of using Scanner from this standard library documentation: https://pkg.go.dev/[email protected]#example-Scanner-Lines

Solution 5 - Go

Another way to read multiple inputs within a loop which can handle an input with spaces:

package main
import (
    "fmt"
    "bufio"
    "os"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    var text string
    for text != "q" {  // break the loop if text == "q"
        fmt.Print("Enter your text: ")
        scanner.Scan()
        text = scanner.Text()
        if text != "q" {
            fmt.Println("Your text was: ", text)
        }
    }
}

Output:

Enter your text: Hello world!
Your text was:  Hello world!
Enter your text: Go is awesome!
Your text was:  Go is awesome!
Enter your text: q

Solution 6 - Go

It can also be done like this:

package main
import "fmt"

func main(){
    var myname string
    fmt.Scanf("%s", &myname)
    fmt.Println("Hello", myname)
}

Solution 7 - Go

I'm late to the party. But how about one liner:

data, err := ioutil.ReadAll(os.Stdin)

And press ctrl+d once done.

Solution 8 - Go

Cleanly read in a couple of prompted values:

// Create a single reader which can be called multiple times
reader := bufio.NewReader(os.Stdin)
// Prompt and read
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Print("Enter More text: ")
text2, _ := reader.ReadString('\n')
// Trim whitespace and print
fmt.Printf("Text1: \"%s\", Text2: \"%s\"\n",
    strings.TrimSpace(text), strings.TrimSpace(text2))

Here's a run:

Enter text: Jim
Enter More text: Susie
Text1: "Jim", Text2: "Susie"

Solution 9 - Go

Try this code:

var input string
func main() {
    fmt.Print("Enter Your Name=")
    fmt.Scanf("%s", &input)
    fmt.Println("Hello " + input)
}

Solution 10 - Go

You need to provide a pointer to the variable you want to scan, like so:

fmt.scan(&text2)

Solution 11 - Go

In my case, the program was not waiting because I was using the watcher command to auto run the program. Manually running the program go run main.go resulted in "Enter text" and eventually printing to the console.

fmt.Print("Enter text: ")
var input string
fmt.Scanln(&input)
fmt.Print(input)

Solution 12 - Go

Let's do it very simple

s:=""
b := make([]byte, 1)
for os.Stdin.Read(b) ; b[0]!='\n'; os.Stdin.Read(b) {
	s+=string(b)
	}
fmt.Println(s)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanteView Question on Stackoverflow
Solution 1 - GoLinearView Answer on Stackoverflow
Solution 2 - GoHelin WangView Answer on Stackoverflow
Solution 3 - GoPithView Answer on Stackoverflow
Solution 4 - GoNaren YellavulaView Answer on Stackoverflow
Solution 5 - GoChiheb NexusView Answer on Stackoverflow
Solution 6 - GoNitin yadavView Answer on Stackoverflow
Solution 7 - GoShivendra MishraView Answer on Stackoverflow
Solution 8 - GoRohanthewizView Answer on Stackoverflow
Solution 9 - GoShivam SharmaView Answer on Stackoverflow
Solution 10 - GoLiam MertensView Answer on Stackoverflow
Solution 11 - GoR SunView Answer on Stackoverflow
Solution 12 - GoArnaud CelermajerView Answer on Stackoverflow