15. Mendapatkan input
Sejauh ini kamu menulis sendiri setiap nilai: mudah ditebak, tapi tidak interaktif. Bab ini membaca apa yang diketik pengguna di terminal.
Untuk ini Go butuh beberapa baris lebih banyak daripada untuk mencetak, dan tiga package tambahan. Bab ini membahasnya satu per satu.
Membaca satu baris
Ini program lengkapnya, dari
exercises/15/01-read-name.go:
// Chapter 15 example: read a name and greet.
// Run with: go run exercises/15/01-read-name.go
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("What is your name?")
text, _ := reader.ReadString('\n')
name := strings.TrimSpace(text)
fmt.Println("Hello, " + name)
}Jalankan. Program mencetak pertanyaan, menunggu namamu dan Enter, mencetak sapaan, lalu selesai. Ada tiga baris yang melakukan pekerjaan baru:
reader := bufio.NewReader(os.Stdin)membuat variabel yang bisa membaca dari keyboard.os.Stdin("standard input") adalah apa yang diketik pengguna di terminal, danbufioadalah package yang membacanya dalam potongan yang praktis. Sebuah program butuh baris ini sekali, sebelum pembacaan pertama.text, _ := reader.ReadString('\n')menunggu pengguna, lalu membaca semuanya sampai dan termasuk akhir baris.'\n'berarti "berhenti di baris baru". Tanda kutipnya tunggal karena ini satu karakter, bukan string. Sepertistrconv.Atoidi Bab 14, fungsi ini mengembalikan dua nilai, dan_membuang nilai kedua. Bab 21 menjelaskannya.name := strings.TrimSpace(text)menghapus akhiran baris. Bagian berikutnya menjelaskan mengapa ini tidak boleh dilewati.
Buka exercises/15/01-read-name.go dan jalankan dua kali
dengan nama yang berbeda. Perhatikan sapaannya berubah mengikuti nama
itu.
Mengapa TrimSpace
wajib
ReadString menyimpan akhiran baris sebagai bagian dari
teks. Di Windows, menekan Enter menaruh dua karakter di akhir baris:
\r dan \n. Jadi kalau kamu mengetik
Keiko, text berisi tujuh byte, bukan lima.
Penanda %q mencetak string dengan tanda kutip di
sekelilingnya dan karakter khususnya terlihat.
exercises/15/05-line-ending.go memakainya untuk menunjukkan
apa yang sebenarnya diterima. Di Windows, mengetik 7 lalu
menekan Enter mencetak:
Type a number: 7
"7\r\n"
"7"
Without TrimSpace: 0
With TrimSpace: 7
strings.TrimSpace menghapus spasi, tab, dan akhiran
baris dari kedua ujung string. Tanpa fungsi ini, dua hal menjadi
salah:
- Teks tercetak berantakan.
fmt.Println("Hello, " + text + "!")menaruh!di baris di bawah nama, karena akhiran barisnya ada di dalamtext. - Angka menjadi
0. Bagistrconv.Atoi,"7\r\n"bukan angka, seperti yang ditunjukkan baris-baris terakhir output di atas.
Jadi setiap pembacaan di buku ini diikuti
strings.TrimSpace.
Prompt di baris yang sama
fmt.Println pindah ke baris baru setelah pertanyaan,
jadi pengguna mengetik di bawahnya. Untuk menjaga kursor di baris yang
sama, gunakan fmt.Print, yang tidak menambahkan baris baru,
dan akhiri prompt dengan spasi. Di dalam main, dengan
import yang sama:
reader := bufio.NewReader(os.Stdin)
fmt.Print("What is your name? ")
text, _ := reader.ReadString('\n')
name := strings.TrimSpace(text)
fmt.Println("Hello, " + name)Output:
What is your name? Keiko
Hello, Keiko
Ini adalah exercises/15/02-prompt-same-line.go.
Membaca angka
ReadString selalu memberikan string,
bahkan untuk digit. Untuk berhitung, rapikan dan konversi dengan
strconv.Atoi dari Bab 14. Tambahkan "strconv"
ke import:
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter a number: ")
text, _ := reader.ReadString('\n')
number, _ := strconv.Atoi(strings.TrimSpace(text))
fmt.Printf("Twice that is %d\n", number*2)Baris konversi berisi dua panggilan sekaligus. Panggilan di dalam
berjalan lebih dulu dan memberikan string yang sudah dirapikan;
panggilan di luar mengubahnya menjadi int. Ini adalah
exercises/15/03-read-number.go.
Untuk desimal, gunakan strconv.ParseFloat dengan cara
yang sama:
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter a decimal: ")
text, _ := reader.ReadString('\n')
x, _ := strconv.ParseFloat(strings.TrimSpace(text), 64)
fmt.Printf("Twice that is %.2f\n", x*2)Kalau pengguna mengetik sesuatu yang bukan bilangan bulat, seperti
abc, 1.5, atau tidak mengetik apa-apa,
strconv.Atoi memberikan 0. Program
tidak crash dan tidak mencetak pesan; program berjalan
terus dengan 0, seolah-olah pengguna mengetiknya.
strconv.ParseFloat melakukan hal yang sama. Nilai kedua
yang dibuang _ adalah satu-satunya yang melaporkan
masalahnya. Kamu akan memeriksanya di Bab 21. Untuk sekarang, ketik
angka saat program memintanya, dan kalau jawabannya salah, lihat apa
yang kamu ketik. (Satu pengecualian: bilangan bulat yang terlalu besar
untuk int memberikan int terbesar, bukan 0.)
Membaca beberapa nilai
Untuk membaca beberapa nilai, panggil ReadString sekali
per nilai, selalu pada reader yang sama:
reader := bufio.NewReader(os.Stdin)
fmt.Print("First number: ")
text, _ := reader.ReadString('\n')
a, _ := strconv.Atoi(strings.TrimSpace(text))
fmt.Print("Second number: ")
text, _ = reader.ReadString('\n')
b, _ := strconv.Atoi(strings.TrimSpace(text))
fmt.Printf("Sum: %d\n", a+b)Setiap panggilan berhenti dan menunggu sendiri-sendiri. Program tidak
lanjut ke baris berikutnya sampai Enter ditekan. Ini adalah
exercises/15/04-read-two.go.
Perhatikan pembacaan kedua. text sudah ada, jadi baris
itu memakai =, dan _ bukan variabel, jadi
tidak dihitung sebagai baru. Menulis := di sana berhenti
dengan no new variables on left side of :=. Di baris
bawahnya, b, _ := boleh, karena b baru.
Kamu mengulang baris-baris ini untuk setiap nilai. Bab 21 menunjukkan cara memasukkannya ke dalam fungsi buatanmu sendiri dan menulisnya sekali saja.
PR
Starter PR hanya mengimpor fmt, dan komentar paling
atasnya menunjukkan import yang kamu butuhkan. Ingat bahwa ekstensi Go
untuk VS Code mungkin menambahkannya untukmu saat kamu menyimpan
file.
Soal 1 — Sapa dengan nama
Buka exercises/15/homework/01-greet-by-name.go. Minta
nama depan dengan fmt.Print, baca, rapikan, lalu cetak
Hello, <name>!. Tanda seru adalah bagian dari
output.
Soal 2 — Jumlah dua angka
Buka exercises/15/homework/02-sum-of-two.go. Minta dua
angka (dengan prompt terpisah), konversi masing-masing dengan
strconv.Atoi, lalu cetak jumlahnya seperti ini:
a + b = c
dengan a, b, c adalah nilai
sebenarnya.
Soal 3 — Tahun menuju pensiun
Buka exercises/15/homework/03-retirement.go. Tanyakan
umur pengguna dan hitung sisa tahun sampai umur 65. Cetak:
You have N years until retirement.
(Kalau seseorang berumur lebih dari 65, angkanya negatif. Tidak apa-apa — belum perlu menangani kasus itu.)
Tantangan — BMI
Buka exercises/15/homework/04-bmi.go. Minta tinggi dalam
meter (desimal seperti 1.78) dan berat dalam kilogram
(seperti 72.5). Gunakan strconv.ParseFloat
untuk mengonversi keduanya. Hitung Indeks Massa Tubuh:
bmi := weight / (height * height)
Cetak hasilnya dengan satu angka desimal menggunakan
fmt.Printf dengan %.1f. Beri label yang
jelas.
Stuck atau sudah selesai? Buka halaman solusi PR.