Meydan okuma 4 - CLI aracı
- Go kursu
- Orta seviye
- Ders 80/80
- 8 dk
flag ile dosya işleyen bir CLI aracı yazarsın.
Meydan okuma: satır sayma aracı
Unix wc benzeri bir CLI aracı yazacaksın. Kurallar: -l verilirse yalnızca satır sayısını, verilmezse satır, kelime ve bayt sayısını yazdırır. Girdi stdin'den okunur; test edilebilmesi için tüm mantık run(args, in, out) fonksiyonunda olur.
printf "a b\nc\n" | ./say # 2 3 6
printf "a b\nc\n" | ./say -l # 2Plan
1) FlagSet ile -l bool seçeneği. 2) veri, err := io.ReadAll(in). 3) Satır: bytes.Count(veri, []byte("\n")); kelime: len(strings.Fields(string(veri))); bayt: len(veri). 4) -l ise yalnızca satırı, değilse üçünü fmt.Fprintln(out, ...) ile yaz. 5) main'de hata olursa stderr'e yazıp os.Exit(1).
Uygulama Aracı yaz
Planı uygula. main içinde run(nil, strings.NewReader("a b\nc\n"), os.Stdout) ve run([]string{"-l"}, strings.NewReader("a b\nc\n"), os.Stdout) çağır.
Başlangıç kodu
package main
import (
"bytes"
"flag"
"fmt"
"io"
"os"
"strings"
)
func main() {
// buraya yaz
}Örnek çözüm
package main
import (
"bytes"
"flag"
"fmt"
"io"
"os"
"strings"
)
func run(args []string, in io.Reader, out io.Writer) error {
fs := flag.NewFlagSet("say", flag.ContinueOnError)
l := fs.Bool("l", false, "yalnızca satır sayısı")
if err := fs.Parse(args); err != nil {
return err
}
veri, err := io.ReadAll(in)
if err != nil {
return err
}
lines := bytes.Count(veri, []byte("\n"))
if *l {
_, err = fmt.Fprintln(out, lines)
return err
}
_, err = fmt.Fprintln(out, lines, len(strings.Fields(string(veri))), len(veri))
return err
}
func main() {
for _, a := range [][]string{nil, {"-l"}} {
if err := run(a, strings.NewReader("a b\nc\n"), os.Stdout); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
}Beklenen çıktı
2 3 6 2
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Bayt sayısını en doğru hangisiyle bulursun?
- utf8.RuneCount
- Girdinin tamamını okuyup len(veri) Doğru cevap
- Satır uzunluklarını toplamak
- Kelime sayısı × 5
Açıklama: Scanner satır sonlarını atar; satır uzunluklarını toplamak \n baytlarını kaçırır. RuneCount ise karakter sayar, bayt değil.
2 Satırları say
lines := bytes.____(veri, []byte("
"))
lines := bytes.Count(veri, []byte("
"))
Açıklama: bytes.Count bir alt dizinin kaç kez geçtiğini sayar; satır sonu sayısı satır sayısıdır.
3 Ölçüm ve yöntem
| Kavram | Anlamı |
|---|---|
Satır |
bytes.Count(\n) |
Kelime |
strings.Fields |
Bayt |
len(veri) |
Karakter |
utf8.RuneCount |