DEV Community

csm
csm

Posted on

taking input with spaces in go

#go

Context

I was writing a calculator program which asks user for input expression and prints the result and prompts again for next expression.

Problem

But, when I used fmt.Scanln() for reading a line(with space-chars like space and tab), the thing happened!

It stopped reading when it encountered a space-char(yep! not a newline but space char).

For example:
Input: 2 +3.5(5)
Got: 2

But, I got even worse thing to say!

The rest of the chars in the input were still there and if we call the Scanln() func again, it reads them.

Solution:

There is another func called Scanf() in fmt package.
This guy is different!
It takes input based on format specifiers and stores them in variables we gave.
Code:

    text := ""

    fmt.Println("Enter expression:")
    for {
        var temp rune
        fmt.Scanf("%c", &temp)
        if temp == '\n' {
            break
        }
        text += string(temp)
    }
    fmt.Printf("You entered:\n %v", text)
Enter fullscreen mode Exit fullscreen mode

Explanation:
1.Prints "Enter expression:"
2.a loop starts
3.Now, the loop takes input from user, char by char(rune by rune in go)
5.And in each iteration, we take that rune and add it or append it to our text variable.
6.When it reads a '\n', then it breaks the loop and we get the input-line inside text variable.
7.Here, rune can also be space chars.
So, literally it reads even the '\n'.

(Reading space chars is an exception for Scanf("%c",&var_name) and is what we want!)

Note: It also solves the problem we get when we read more than one line.I mean, we get unexpected input or behaviour when we read more than one line(I don't know the exact reason!).
But here, since we are reading char by char, including '\n' as well(into the temp var), will eliminate all those errors!

Custom readline() func

We can write a custom readline() func like this:

package main

import "fmt"

func main() {

    fmt.Println("Enter expression:")
    input := readline()
    fmt.Printf("You entered:\n %v\n", input)

}

func readline() string {
    var text string
    for {
        var temp rune
        fmt.Scanf("%c", &temp)
        if temp == '\n' {
            break
        }
        text += string(temp)
    }
    return text

}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)