av192
av192

Reputation: 482

golang accepting input with spaces

I'm just starting with GO and I understand that SCANF uses spaces as a separator in GO.

fmt.Scanf("%s",&input)

I cant really find a way to accepts inputs that contain spaces as valid characters.

Upvotes: 28

Views: 39811

Answers (4)

sethammons
sethammons

Reputation: 771

Similar to @chlin's answer, use bufio to capture whole lines.

The fmt Scan methods store each space separated value into a successive arguments. Three arguments on stdin would require something like:

package main

import "fmt"

func main() {
    var day, year int
    var month string
    fmt.Scanf("%d %s %d", &day, &month, &year)
    fmt.Printf("captured: %d %s %d\n", day, month, year)
}

If you don't know the full format of what you will be reading and just want the line, use bufio:

package main

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

func main(){
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan() // use `for scanner.Scan()` to keep reading
    line := scanner.Text()
    fmt.Println("captured:",line)
}

Upvotes: 40

VonC
VonC

Reputation: 1324178

My initial 2014 answer used fmt.Scanln for this specific use case.
But fmt.Scanln also treats spaces as separators between inputs. That means it cannot directly read an entire line including spaces into a single string variable without additional handling.


A better option would be to use bufio.NewReader and its ReadString method.
Unlike fmt.Scanln, bufio.NewReader with ReadString allows you to read an entire line of input, including spaces, into a single string until a newline character is encountered. That behavior is precisely what is needed to accept inputs like "Hello there" as a single string.

Using fmt.Scanln:        "Hello there" → "Hello"
Using bufio.NewReader:   "Hello there" → "Hello there"

Using bufio.NewReader to read a line of input, including spaces, until the user presses Enter (newline), would be:

package main

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

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    input, err := reader.ReadString('\n') // '\n' is the delimiter to stop reading
    if err != nil {
        fmt.Println(err)
        return
    }

    // Trim the newline character from the input, if any
    input = strings.TrimSpace(input) 

    fmt.Println("You entered:", input)
}

You can test it on playground go.dev/play.

Remember, the ReadString method returns the delimiter as part of the input, so you may want to trim the input string to remove the newline character at the end.

Upvotes: -6

stackoverflowsucks
stackoverflowsucks

Reputation: 247

When using ReadString('\n'), it reads until and including the newline character. If you want to remove this trailing newline from the input string, you can use the strings.TrimSpace function.

package main

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

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Please enter a string: ")
    text, _ := reader.ReadString('\n')
    text = strings.TrimSpace(text)  // Remove any surrounding whitespace including the newline.
    fmt.Printf("You entered: %s", text)
}

Upvotes: 3

rchlin
rchlin

Reputation: 567

you can use bufio.Reader and os.Stdin:

import(
  "bufio"
  "os"
)

in := bufio.NewReader(os.Stdin)

line, err := in.ReadString('\n')

Upvotes: 45

Related Questions