String with spaces


(Dattatray Jadhav) #1

HI All,
How do I read the complete string with spaces? any help please

package main

import “fmt”

func main() {
var name string
fmt.Print("Enter full name : ")
fmt.Scan(&name)
fmt.Println(“The full name is-”, name)
}

Here if i give input as , Go Program
i get the output as " The full name is- Go"

Thank you!


(Johan Dahl) #2

Hi. Use fmt.Scanln instead. It reads input to the next newline. fmt.Scan just reads to next space (or newline which comes first)


(Dattatray Jadhav) #3

fmt.Scanln doesnt really work. It still does not consider the spaces.


(Norbert Melzer) #4

Scan is for reading in space separated tokens, you can’t use it the way you want.

Just use a reader from stdin.


(Jay Ts) #5

Here is one way to do it. I used ReadRune() to show some extra details. You might want to use bufio.ReadString() or bufio.ReadBytes() instead.

package main

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


func main() {

        var stdin *bufio.Reader
        var line []rune
        var c rune
        var err error

        stdin = bufio.NewReader(os.Stdin)

        fmt.Printf("Type something: ")

        for {
                c, _, err = stdin.ReadRune()
                if err == io.EOF || c == '\n' { break }
                if err != nil {
                        fmt.Fprintf(os.Stderr,"Error reading standard input\n")
                        os.Exit(1)
                }
                line = append(line,c)
        }

        fmt.Printf("\nYou entered: %s\n",string(line[:len(line)]))
}

(Johan Dahl) #6

My error Scanln is called with multiple arguments and each should be separated by spaces

fmt.Scanln(&a, &b, &c) and if you write “Home sweet home” will a == “Home”, b == “sweet” and c == “home”. You could use Scanner from bufio instead

package main

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

func main() {

	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("> ")
	if scanner.Scan() {
		fmt.Printf("You wrote \"%s\"\n", scanner.Text())
	}
}

and now you could also loop and get each line you write

package main

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

func main() {

	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("> ")
	for scanner.Scan() {
		fmt.Printf("You wrote \"%s\"\n", scanner.Text())
		fmt.Print("> ")
	}
}

(Dattatray Jadhav) #7

Wow, Thanks a lot Jayts it worked for me, Now I would need to understand the code. It looks bit complex and high level for me.

When you get some time would please help me to understand the below lines of your code.

stdin = bufio.NewReader(os.Stdin)

    fmt.Printf("Type something: ")

    for {
            c, _, err = stdin.ReadRune()
            if err == io.EOF || c == '\n' { break }
            if err != nil {
                    fmt.Fprintf(os.Stderr,"Error reading standard input\n")
                    os.Exit(1)
            }
            line = append(line,c)
    }

(Jay Ts) #8

Here are some notes to explain it. First, mostly all you need is to understand the bufio package. The documentation for that is here:

https://golang.org/pkg/bufio/

In my example,

stdin = bufio.NewReader(os.Stdin)

gets a handle (called a “Reader”) for buffered reading from the standard input (console input) using other methods in bufio.

 c, _, err = stdin.ReadRune()

This reads a rune from the standard input.ReadRune() returns 3 values: the rune, the number of bytes it takes up, and an error type. I use the blank identifier (_) for the second return value because I don’t use it for anything. (If you don’t need to support Unicode and use ReadByte() instead, then there are only two return values, and the blank identifier would not be needed.)

After ReadRune() returns, c contains the rune that was read, and err can be checked to see if an error happened, or if the end of the file was encountered.

if err == io.EOF || c == '\n' { break }

Next, I check to see if it has encountered the end of file (in which case err will be set to io.EOF), or made it to the end of the line (and has read a newline, \n). In the four lines after that, I catch any other error condition that ReadRune() may have encountered.

line = append(line,c)

If things went ok reading the character, I append it toline[], which is a slice of runes. (append() is one of Go’s built-in functions.)

Otherwise, the loop terminates, and I print the result. Notice that I don’t save the newline in the slice, so I have to add a newline with the Printf() call. The %s verb in the literal string given to Printf() expects a string type, so

string(line[:len(line)])

is in there to convert the slice of runes into a string.


(system) closed #9

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.