Input and Output
package main
import "fmt"
func main() {
fmt.Println("Hello 世界!")
}The first introductory example on this site was outputting a string. This section explains how to perform input and output in Go.
File Descriptors
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)In the os package, there are three externally exposed file descriptors, all of type *os.File:
os.Stdin- Standard Inputos.Stdout- Standard Outputos.Stderr- Standard Error
Input and output in Go are all done through these.
Output
There are many ways to output in Go. Here are some common ones:
stdout
Since standard output is itself a file, you can directly write strings to standard output:
package main
import "os"
func main() {
os.Stdout.WriteString("hello world!")
}print
Go has two built-in functions, print and println. They output parameters to standard error and are only used for debugging. They are generally not recommended.
package main
func main() {
print("hello world!\n")
println("hello world")
}fmt
The most common usage is to use the fmt package. It provides the fmt.Println function, which outputs parameters to standard output by default.
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}It accepts parameters of any type. If the type implements the String interface, it will call the String method to get its string representation. Therefore, the output is highly readable and suitable for most scenarios. However, since it uses reflection internally, it is not recommended for heavy use in performance-sensitive scenarios.
bufio
bufio provides buffered output methods. It first writes data to memory and outputs to the specified Writer when a certain threshold is reached. The default buffer size is 4KB. It is recommended to use this package for file I/O and network I/O.
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
writer.WriteString("hello world!")
}You can also combine it with the fmt package:
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
fmt.Fprintln(writer, "hello world!")
}Formatting
The formatted output functionality in Go is basically provided by the fmt.Printf function. If you have learned C-like languages, it will feel very familiar. Here is a simple example:
func main() {
fmt.Printf("hello world, %s!", "jack")
}Below are all the current format verbs in Go:
| # | Format | Description | Accepted Types |
|---|---|---|---|
| 1 | %% | Outputs a percent sign % | Any |
| 2 | %s | Outputs string/[] byte value | string,[] byte |
| 3 | %q | Formats string, output has double quotes "" around the string | string,[] byte |
| 4 | %d | Outputs decimal integer value | Integer |
| 5 | %f | Outputs floating point number | Floating point |
| 6 | %e | Outputs in scientific notation, can also be used for complex numbers | Floating point |
| 7 | %E | Same as %e | Floating point |
| 8 | %g | Determines whether to output %f or %e based on actual situation, removes extra zeros | Floating point |
| 9 | %b | Outputs the binary representation of an integer | Numeric |
| 10 | %#b | Outputs the full binary representation | Numeric |
| 11 | %o | Outputs the octal representation of an integer | Integer |
| 12 | %#o | Outputs the full octal representation of an integer | Integer |
| 13 | %x | Outputs lowercase hexadecimal representation of an integer | Numeric |
| 14 | %#x | Outputs the full lowercase hexadecimal representation of an integer | Numeric |
| 15 | %X | Outputs uppercase hexadecimal representation of an integer | Numeric |
| 16 | %#X | Outputs the full uppercase hexadecimal representation of an integer | Numeric |
| 17 | %v | Outputs the original form of the value, mostly used for data structures | Any |
| 18 | %+v | Outputs struct with field names | Any |
| 19 | %#v | Outputs complete Go syntax format value | Any |
| 20 | %t | Outputs boolean value | Boolean |
| 21 | %T | Outputs the corresponding Go language type value | Any |
| 22 | %c | Outputs the character corresponding to the Unicode code point | int32 |
| 23 | %U | Outputs the Unicode code point corresponding to the character | rune,byte |
| 24 | %p | Outputs the address pointed to by the pointer | Pointer |
Use fmt.Sprintf or fmt.Printf to format strings or output formatted strings. Here are some examples:
fmt.Printf("%%%s\n", "hello world")
fmt.Printf("%s\n", "hello world")
fmt.Printf("%q\n", "hello world")
fmt.Printf("%d\n", 2<<7-1)
fmt.Printf("%f\n", 1e2)
fmt.Printf("%e\n", 1e2)
fmt.Printf("%E\n", 1e2)
fmt.Printf("%g\n", 1e2)
fmt.Printf("%b\n", 2<<7-1)
fmt.Printf("%#b\n", 2<<7-1)
fmt.Printf("%o\n", 2<<7-1)
fmt.Printf("%#o\n", 2<<7-1)
fmt.Printf("%x\n", 2<<7-1)
fmt.Printf("%#x\n", 2<<7-1)
fmt.Printf("%X\n", 2<<7-1)
fmt.Printf("%#X\n", 2<<7-1)
type person struct {
name string
age int
address string
}
fmt.Printf("%v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%+v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%#v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%t\n", true)
fmt.Printf("%T\n", person{})
fmt.Printf("%c%c\n", 20050, 20051)
fmt.Printf("%U\n", '码')
fmt.Printf("%p\n", &person{})When using other bases, adding a space between % and the format verb can achieve the effect of a separator:
func main() {
str := "abcdefg"
fmt.Printf("%x\n", str)
fmt.Printf("% x\n", str)
}The output of this example is:
61626364656667
61 62 63 64 65 66 67When using numbers, you can also automatically pad with zeros:
fmt.Printf("%09d", 1)
// 000000001Same for binary:
fmt.Printf("%09b", 1<<3)
// 000001000Error Cases
Number of format specifiers < number of arguments:
fmt.Printf("", "") //%!(EXTRA string=)Number of format specifiers > number of arguments:
fmt.Printf("%s%s", "") //%!s(MISSING)Type mismatch:
fmt.Printf("%s", 1) //%!s(int=1)Missing format verb:
fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)Input
Common input methods are introduced below:
read
You can read input content like reading a file directly:
func main() {
var buf [1024]byte
n, _ := os.Stdin.Read(buf[:])
os.Stdout.Write(buf[:n])
}This is too cumbersome to use and is generally not recommended.
fmt
We can use the functions provided by the fmt package, which are similar to C.
// Scans text read from os.Stdin, separated by whitespace, newlines are also treated as whitespace
func Scan(a ...any) (n int, err error)
// Similar to Scan, but stops scanning when encountering a newline
func Scanln(a ...any) (n int, err error)
// Scans according to a formatted string
func Scanf(format string, a ...any) (n int, err error)Read two numbers:
func main() {
var a, b int
fmt.Scanln(&a, &b)
fmt.Printf("%d + %d = %d\n", a, b, a+b)
}Read a fixed-length array:
func main() {
n := 10
s := make([]int, n)
for i := range n {
fmt.Scan(&s[i])
}
fmt.Println(s)
}1 2 3 4 5 6 7 8 9 10
[1 2 3 4 5 6 7 8 9 10]bufio
When there is a large amount of input to read, it is recommended to use bufio.Reader for reading content:
func main() {
reader := bufio.NewReader(os.Stdin)
var a, b int
fmt.Fscanln(reader, &a, &b)
fmt.Printf("%d + %d = %d\n", a, b, a+b)
}scanner
bufio.Scanner is similar to bufio.Reader, but it reads line by line.
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
if line == "exit" {
break
}
fmt.Println("scan", line)
}
}The result is:
first line
scan first line
second line
scan second line
third line
scan third line
exitTIP
For practicing input and output, you can go to Luogu and solve a few simple ACM-style algorithm problems to get familiar with it.
