อินพุตเอาต์พุตใน Go
package main
import "fmt"
func main() {
fmt.Println("Hello โลก!")
}กรณีตัวอย่างแรก在本站คือการเอาต์พุตสตริงหนึ่งสตริง บทนี้จะกล่าวถึงวิธีการอินพุตเอาต์พุตใน Go
ตัวอธิบายไฟล์
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)ในแพ็กเกจ os มีตัวอธิบายไฟล์ที่เปิดเผยภายนอกสามตัว ประเภทของพวกมันคือ *os.File ได้แก่
os.Stdin- อินพุตมาตรฐานos.Stdout- เอาต์พุตมาตรฐานos.Stderr- ข้อผิดพลาดมาตรฐาน
อินพุตเอาต์พุตใน Go ไม่สามารถแยกจากพวกมันได้
เอาต์พุต
ใน Go มีวิธีการเอาต์พุตหลายวิธี ด้านล่างเป็นวิธีที่พบบ่อยบางวิธี
stdout
เนื่องจากเอาต์พุตมาตรฐานเป็นไฟล์อยู่แล้ว คุณสามารถเขียนสตริงลงในเอาต์พุตมาตรฐานได้โดยตรง
package main
import "os"
func main() {
os.Stdout.WriteString("hello world!")
}print
Go มีฟังก์ชันในตัวสองฟังก์ชัน print, println พวกมันจะเอาต์พุตพารามิเตอร์ไปยังข้อผิดพลาดมาตรฐาน ใช้สำหรับการดีบักเท่านั้น โดยทั่วไปไม่แนะนำให้ใช้
package main
func main() {
print("hello world!\n")
println("hello world")
}fmt
วิธีที่ใช้บ่อยที่สุดคือการใช้แพ็กเกจ fmt มันมีฟังก์ชัน fmt.Println ซึ่งโดยค่าเริ่มต้นจะเอาต์พุตพารามิเตอร์ไปยังเอาต์พุตมาตรฐาน
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}พารามิเตอร์ของมันรองรับประเภทใดๆ หากประเภทใช้อินเทอร์เฟซ String จะเรียกเมธอด String เพื่อรับรูปแบบสตริงของมัน ดังนั้นเนื้อหาที่เอาต์พุตมีความสามารถในการอ่านสูง เหมาะสำหรับสถานการณ์ส่วนใหญ่ แต่เนื่องจากใช้การสะท้อนภายใน ไม่แนะนำให้ใช้จำนวนมากในสถานการณ์ที่อ่อนไหวต่อประสิทธิภาพ
bufio
bufio มีวิธีการเอาต์พุตแบบบัฟเฟอร์ มันจะเขียนข้อมูลลงในหน่วยความจำก่อน เมื่อสะสมถึงเกณฑ์ที่กำหนดจึงเอาต์พุตไปยัง Writer ที่กำหนด ขนาดบัฟเฟอร์เริ่มต้นคือ 4KB แนะนำให้ใช้แพ็กเกจนี้เมื่อทำ IO ไฟล์ หรือ IO เครือข่าย
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
writer.WriteString("hello world!")
}คุณยังสามารถรวม它与แพ็กเกจ fmt ใช้ร่วมกันได้
func main() {
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
fmt.Fprintln(writer, "hello world!")
}การจัดรูปแบบ
ฟังก์ชันการจัดรูปแบบเอาต์พุตใน Go โดยพื้นฐานแล้วมีให้โดยฟังก์ชัน fmt.Printf หากคุณเรียนรู้ภาษาตระกูล C มาแล้ว จะต้องรู้สึกคุ้นเคย ด้านล่างเป็นตัวอย่างง่ายๆ
func main() {
fmt.Printf("hello world, %s!", "jack")
}ด้านล่างเป็นคำกริยาการจัดรูปแบบทั้งหมดที่ Go มีในปัจจุบัน
| 0 | การจัดรูปแบบ | คำอธิบาย | ประเภทที่รับ |
|---|---|---|---|
| 1 | %% | เอาต์พุตเครื่องหมายเปอร์เซ็นต์ % | ใดๆ |
| 2 | %s | เอาต์พุตค่า string/[] byte | string,[] byte |
| 3 | %q | จัดรูปแบบสตริง สตริงที่เอาต์พุตมีเครื่องหมายอัญประกาศคู่ "" ล้อมรอบ | string,[] byte |
| 4 | %d | เอาต์พุตค่าจำนวนเต็มฐานสิบ | จำนวนเต็ม |
| 5 | %f | เอาต์พุตจำนวนจริง | จำนวนจริง |
| 6 | %e | เอาต์พุตในรูปแบบสัญกรณ์วิทยาศาสตร์ ใช้กับจำนวนเชิงซ้อนได้ | จำนวนจริง |
| 7 | %E | เหมือนกับ %e | จำนวนจริง |
| 8 | %g | ตัดสินใจเอาต์พุต %f หรือ %e ตามสถานการณ์จริง จะลบ 0 ที่เกินออก | จำนวนจริง |
| 9 | %b | เอาต์พุตในรูปแบบไบนารีของจำนวนเต็ม | ตัวเลข |
| 10 | %#b | เอาต์พุตในรูปแบบไบนารีที่สมบูรณ์ | ตัวเลข |
| 11 | %o | เอาต์พุตในรูปแบบแปดฐานของจำนวนเต็ม | จำนวนเต็ม |
| 12 | %#o | เอาต์พุตในรูปแบบแปดฐานที่สมบูรณ์ของจำนวนเต็ม | จำนวนเต็ม |
| 13 | %x | เอาต์พุตในรูปแบบสิบหกฐานตัวเล็กของจำนวนเต็ม | ตัวเลข |
| 14 | %#x | เอาต์พุตในรูปแบบสิบหกฐานตัวเล็กที่สมบูรณ์ของจำนวนเต็ม | ตัวเลข |
| 15 | %X | เอาต์พุตในรูปแบบสิบหกฐานตัวใหญ่ของจำนวนเต็ม | ตัวเลข |
| 16 | %#X | เอาต์พุตในรูปแบบสิบหกฐานตัวใหญ่ที่สมบูรณ์ของจำนวนเต็ม | ตัวเลข |
| 17 | %v | เอาต์พุตในรูปแบบเดิมของค่า ส่วนใหญ่ใช้สำหรับการเอาต์พุตโครงสร้างข้อมูล | ใดๆ |
| 18 | %+v | เมื่อเอาต์พุตสตรักเจอร์จะเพิ่มชื่อฟิลด์ด้วย | ใดๆ |
| 19 | %#v | เอาต์พุตค่าในรูปแบบไวยากรณ์ Go ที่สมบูรณ์ | ใดๆ |
| 20 | %t | เอาต์พุตค่าบูลีน | บูลีน |
| 21 | %T | เอาต์พุตค่าประเภทภาษา Go ที่ตรงกับค่า | ใดๆ |
| 22 | %c | เอาต์พุตอักขระที่ตรงกับรหัส Unicode | int32 |
| 23 | %U | เอาต์พุตรหัส Unicode ที่ตรงกับอักขระ | rune,byte |
| 24 | %p | เอาต์พุตที่อยู่ของพอยน์เตอร์ที่ชี้ | พอยน์เตอร์ |
ใช้ fmt.Sprintf หรือ fmt.Printf เพื่อจัดรูปแบบสตริงหรือเอาต์พุตสตริงที่จัดรูปแบบ ดูตัวอย่างบางตัวอย่าง
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{})เมื่อใช้ฐานอื่น สามารถเพิ่มช่องว่างระหว่าง % กับคำกริยาจัดรูปแบบเพื่อให้ได้ผลของตัวคั่น เช่น
func main() {
str := "abcdefg"
fmt.Printf("%x\n", str)
fmt.Printf("% x\n", str)
}ผลลัพธ์ของตัวอย่างนี้คือ
61626364656667
61 62 63 64 65 66 67เมื่อใช้ตัวเลข ยังสามารถเติมศูนย์อัตโนมัติได้ เช่น
fmt.Printf("%09d", 1)
// 000000001ไบนารีก็เช่นกัน
fmt.Printf("%09b", 1<<3)
// 000001000สถานการณ์ข้อผิดพลาด
จำนวนอักขระจัดรูปแบบ < จำนวนพารามิเตอร์ในรายการ
fmt.Printf("", "") //%!(EXTRA string=)จำนวนอักขระจัดรูปแบบ > จำนวนพารามิเตอร์ในรายการ
fmt.Printf("%s%s", "") //%!s(MISSING)ประเภทไม่ตรงกัน
fmt.Printf("%s", 1) //%!s(int=1)ขาดคำกริยาจัดรูปแบบ
fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)อินพุต
ด้านล่างแนะนำวิธีการอินพุตที่พบบ่อย
read
คุณสามารถอ่านเนื้อหาอินพุตเหมือนอ่านไฟล์โดยตรง ดังนี้
func main() {
var buf [1024]byte
n, _ := os.Stdin.Read(buf[:])
os.Stdout.Write(buf[:n])
}แบบนี้ใช้ยากเกินไป โดยทั่วไปไม่แนะนำให้ใช้
fmt
เราสามารถใช้ฟังก์ชันบางฟังก์ชันที่แพ็กเกจ fmt มีให้ ใช้คล้ายกับ C
// สแกนข้อความที่อ่านจาก os.Stdin แยกตามช่องว่าง ขึ้นบรรทัดใหม่ก็ถือเป็นช่องว่างด้วย
func Scan(a ...any) (n int, err error)
// คล้ายกับ Scan แต่หยุดการสแกนเมื่อพบการขึ้นบรรทัดใหม่
func Scanln(a ...any) (n int, err error)
// สแกนตามสตริงที่จัดรูปแบบ
func Scanf(format string, a ...any) (n int, err error)อ่านตัวเลขสองตัว
func main() {
var a, b int
fmt.Scanln(&a, &b)
fmt.Printf("%d + %d = %d\n", a, b, a+b)
}อ่านอาร์เรย์ความยาวคงที่
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
เมื่อมีอินพุตจำนวนมากที่ต้องอ่าน แนะนำให้ใช้ bufio.Reader เพื่ออ่านเนื้อหา
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 คล้ายกับ bufio.Reader แต่จะอ่านทีละบรรทัด
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
if line == "exit" {
break
}
fmt.Println("scan", line)
}
}ผลลัพธ์ดังนี้
first line
scan first line
second line
scan second line
third line
scan third line
exitTIP
ในด้านการอินพุตเอาต์พุตนี้ หากต้องการฝึกฝน ไปที่ 洛谷 ทำโจทย์อัลกอริทึมโหมด ACM ง่ายๆ สองสามข้อก็จะคุ้นเคยได้
