[Golang] Standard I/O with the fmt package

2021-09-29 hit count image

Let's see how to use Standard I/O with the fmt package in Golang.

Outline

In this blog post, I will introduce how to use Standard I/O with the fmt package in Golang.

  • Official site: fmt

You can see the full source code of this blog post on the link below.

Standard output

In Golang, to see how to use the fmt package, make the main.go file and modify it like the below.

package main

import "fmt"

func main() {
    var a int = 10
    var b int = 20
    var f float64 = 3.14

    fmt.Print("a: ", a);
    fmt.Println("b: ", b);
    fmt.Printf("a: %d / f: %f\n", a, f);
}

When you execute the program, you can see the output like the below.

a: 10b:  20
a: 10 / f: 3.140000

Each standard output function has the following characteristics.

  • Print(): print the parameter values in the function without newline.
  • Println(): print the parameter values in the function with newline.
  • Printf(): print the parameter values with Format.

Format

You can use the format below in Printf.

  • %v: print the data in basic format accouding to data type.
  • %T: print the data type.
  • %t: print bool data in true/false.
  • %d: print integer.
  • %b: print in binary.
  • %c: print in unicode characters. (integer only)
  • %o: print in octal.
  • %O: print with Oo in front to indicate octal.
  • %x: print in hexadecimal. if the value is greater than, a-f is used.
  • %X: print in hexadecimal. if the value is greater than, A-F is used.
  • %e: print in exponential. (float only)
  • %E: print in exponential. (float only)
  • %f: print float value as it it. (up to 6 decimal places)
  • %F: print float value as it it.
  • %g: print float value in exponential if the value is big(more than 6 digits). if it is small, print float value as it is.
  • %G: print float value in exponential if the value is big. if it is small, print float value as it is.
  • %s: print string
  • %q: print string and special characters as it is(ex> \n, \t)

Also, you can use the format below for integer to sort.

  • %5d: print to fit 5 spaces (right aligned)
  • %05d: print to fit 5 spaces (0 is printed on empty space)
  • %-5d: print to fit 5 spaces(left aligned)

To check these formats, modify the source code like the below.

func main() {
    a := 1
    b := 10
    c := 100
    d := 1000
    e := 10000

    fmt.Printf("a: %5d\n", a)
    fmt.Printf("b: %5d\n", b)
    fmt.Printf("c: %5d\n", c)
    fmt.Printf("d: %5d\n", d)
    fmt.Printf("e: %5d\n", e)

    fmt.Println()
    fmt.Printf("a: %05d\n", a)
    fmt.Printf("b: %05d\n", b)
    fmt.Printf("c: %05d\n", c)
    fmt.Printf("d: %05d\n", d)
    fmt.Printf("e: %05d\n", e)

    fmt.Println()
    fmt.Printf("a: %-5d\n", a)
    fmt.Printf("b: %-5d\n", b)
    fmt.Printf("c: %-5d\n", c)
    fmt.Printf("d: %-5d\n", d)
    fmt.Printf("e: %-5d\n", e)
}

When you execute the code, you can see the result like the below.

a:     1
b:    10
c:   100
d:  1000
e: 10000

a: 00001
b: 00010
c: 00100
d: 01000
e: 10000

a: 1
b: 10
c: 100
d: 1000
e: 10000

Standard input

You can get the user input with fmt. Modify the main.go file like the below.

package main

import "fmt"

func main() {
    var a int
    var b int

    n, err := fmt.Scanln(&a, &b)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(n, a, b)
    }
}

When you execute the program, you can see the cursor on the screen. (unlike that other programs exit soon.) Then, let’s insert some values like the below.

10 30

When you enter the values, you can see the result like the below.

2 10 30

Scanln stores the user input to the memory of the paramter, and returns the number of values and error if error occurs.

There are more Standard input functions in fmt like the below.

  • Scan(): get the user input.
  • Scanf(): get the user input with the format.
  • Scanln(): read the one line from the Standart input.

You should pass the paramter with & to pass the memory address in Scan. Scan will store the user input to the memory address.

Clear input buffer

If there is a program that has two user inputs like the below.

package main

import "fmt"

func main() {
    var a int
    var b int

    n, err := fmt.Scanln(&a, &b)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(n, a, b)
    }

    n, err = fmt.Scanln(&a, &b)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(n, a, b)
    }
}

And let’s execute the program and insert the values like the below.

3 a

And then, you can see the error message like the below because the variable type and user input data type are different.

expected integer

However, even we wrote the code that gets the user input twice, the second input is not executed and the error occurs like the below.

unexpected newline

When the first error occurred, the contents were still stored in the buffer, and the contents of the buffer were used in second input, so the error occurs.

To sovle this problem, you can clear the input buffer when the error occurs like the below.

package main

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

func main() {
    stdin := bufio.NewReader(os.Stdin)

    var a int
    var b int

    n, err := fmt.Scanln(&a, &b)
    if err != nil {
        fmt.Println(err)
        stdin.ReadString('\n')
    } else {
        fmt.Println(n, a, b)
    }

    n, err = fmt.Scanln(&a, &b)
    if err != nil {
        fmt.Println(err)
        stdin.ReadString('\n')
    } else {
        fmt.Println(n, a, b)
    }
}

When the error occurs, stdin.ReadString('\n') reads the contents of the buffer until a newline character is encountered and clears the buffer.

Completed

Done! we’ve seen how to use the fmt package for Standart I/O. Now, we’ve known that Scan is for the input, and Print is for the output. Also, we’ve known that if the error occurs in the input, the contents of the buffer are not cleared, so we should clear the buffer manually.

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

Posts