How to use fmt.scanln read from a string separated by spaces

23,736

Solution 1

The fmt Scan family scan space-separated tokens.

package main

import (
    "fmt"
)

func main() {
    var s1 string
    var s2 string
    fmt.Scanln(&s1,&s2)
    fmt.Println(s1)
    fmt.Println(s2)
    return
}

You can try bufio scan

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

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        s := scanner.Text()
        fmt.Println(s)
    }
    if err := scanner.Err(); err != nil {
        os.Exit(1)
    }
}

Solution 2

If you really want to include the spaces, you may consider using fmt.Scanf() with format %q a double-quoted string safely escaped with Go syntax , for example:

package main

import "fmt"

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

Run it and:

$ go run test.go
"31 of month"
31 of month

Solution 3

Here is the working program

package main

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

func main() {
    var strInput string
    fmt.Println("Enter a string ")
    scanner := bufio.NewScanner(os.Stdin)

    if scanner.Scan() {
        strInput = scanner.Text()
    }
    
    fmt.Println(strInput)
}

which reads strings like " d skd a efju N" and prints the same string as output.

Share:
23,736
Shuumatsu
Author by

Shuumatsu

Updated on January 28, 2022

Comments

  • Shuumatsu
    Shuumatsu over 2 years

    Want "30 of month" but get "30"

    package main
    
    import "fmt"
    
    func main() {
        var s string
        fmt.Scanln(&s)
        fmt.Println(s)
        return
    }
    
    $ go run test.go
    31 of month
    31
    

    Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.

  • Shuumatsu
    Shuumatsu over 8 years
    thx...but if I put fmt.Println(s) outside of the loop, no values will be output. how can i stop the loop
  • trquoccuong
    trquoccuong over 8 years
    func main() { scanner := bufio.NewScanner(os.Stdin) if ok := scanner.Scan();ok { fmt.Println(scanner.Text()) } } scanner.Scan() will return bool when end scan
  • Ishan Jain
    Ishan Jain about 7 years
    Second snippet worked great. Why are you checking for error after for loop ? would the if else block be executed here in case of an error ? Because there is a infinite for loop before it.
  • tsar2512
    tsar2512 over 6 years
    @trquoccuong - I have the same query as Ishan above, doesn't checking for the error after fmt.Println(s), break things? you are checking scanner.Err() after printing the scan?
  • kamal
    kamal over 6 years
    bufio solution is great!
  • Bayequentist
    Bayequentist almost 6 years
    I have to use an if statement instead of for loop, so that the program will proceed after the first input. If I use a for loop, the program will keep asking me for input forever. How would I get out of the loop if I used a for loop?
  • Venkataramana Madugula
    Venkataramana Madugula over 5 years
    I agree with @Zass
  • gondo
    gondo almost 5 years
    question specifically asked about fmt.scanln, not how to achieve same result with different method
  • Dejan Toteff
    Dejan Toteff over 3 years
    I voted up as this question is accessable from search engine and it indeed works
  • Fernando Torres
    Fernando Torres over 2 years
    With this approach i'm getting: expected quoted string trying to input "hello world" string
  • eemz
    eemz over 2 years
    gondo the answer is "you can't do this with scanln"