Skip to content

Go Giriş Çıkış

go
package main

import "fmt"

func main() {
   fmt.Println("Merhaba Dünya!")
}

Bu sitenin ilk giriş örneği bir string çıktıydı. Bu bölümde Go'da nasıl giriş çıkış yapılacağını anlatacağız.

Dosya Tanımlayıcıları

go
var (
   Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
   Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
   Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)

os paketi altında üç dışa açık dosya tanımlayıcı bulunur, türleri *os.File'dır:

  • os.Stdin - Standart giriş
  • os.Stdout - Standart çıktı
  • os.Stderr - Standart hata

Go'da giriş çıkış bunlardan ayrılmaz.

Çıktı

Go'da çıktı için birçok yöntem vardır, aşağıda birkaç yaygın olanı verilmiştir.

stdout

Standart çıktı doğası gereği bir dosya olduğu için, doğrudan string'i standart çıktıya yazabilirsiniz:

go
package main

import "os"

func main() {
  os.Stdout.WriteString("merhaba dünya!")
}

print

Go'nun iki yerleşik fonksiyonu vardır: print, println. Parametreleri standart hataya çıktı yaparlar, sadece hata ayıklama için kullanılırlar, genellikle önerilmez.

go
package main

func main() {
  print("merhaba dünya!\n")
  println("merhaba dünya")
}

fmt

En yaygın kullanım fmt paketini kullanmaktır, fmt.Println fonksiyonunu sağlar. Bu fonksiyon varsayılan olarak parametreleri standart çıktıya çıktı yapar.

go
package main

import "fmt"

func main() {
  fmt.Println("merhaba dünya!")
}

Parametreleri herhangi bir türü destekler. Eğer tür String arayüzünü uyguluyorsa, string temsilini almak için String metodu da çağrılır, bu yüzden çıktının okunabilirliği yüksektir ve çoğu durum için uygundur. Ancak dahili olarak yansıma kullanıldığı için, performansın hassas olduğu senaryolarda yoğun kullanım önerilmez.

bufio

bufio buffered çıktı yöntemleri sağlar, verileri önce belleğe yazar, belirli bir eşik değerine ulaştığında belirtilen Writer'a çıktı yapar. Varsayılan buffer boyutu 4KB'dır. Dosya IO, ağ IO durumunda bu paketi kullanmanız önerilir.

go
func main() {
  writer := bufio.NewWriter(os.Stdout)
  defer writer.Flush()
  writer.WriteString("merhaba dünya!")
}

Bunu fmt paketi ile birleştirerek de kullanabilirsiniz:

go
func main() {
  writer := bufio.NewWriter(os.Stdout)
  defer writer.Flush()
  fmt.Fprintln(writer, "merhaba dünya!")
}

Biçimlendirme

Go'da biçimlendirilmiş çıktı işlevleri temel olarak fmt.Printf fonksiyonu tarafından sağlanır. Eğer C serisi dilleri öğrendiyseniz, kesinlikle tanıdık gelecektir. Aşağıda basit bir örnek verilmiştir:

go
func main() {
  fmt.Printf("merhaba dünya, %s!", "jack")
}

Aşağıda Go'nun şu anki tüm biçimlendirme belirleyicileri verilmiştir.

NoBiçimlendirmeAçıklamaKabul Eden Türler
1%%Yüzde işareti % çıktısıHerhangi
2%sstring/[] byte değeri çıktısıstring,[] byte
3%qBiçimlendirilmiş string, çıktının iki yanında çift tırnak "" bulunurstring,[] byte
4%dOndalık tamsayı değeri çıktısıTamsayı
5%fOndalık sayı çıktısıOndalık sayı
6%eBilimsel gösterim şeklinde çıktı, karmaşık sayılar için de kullanılabilirOndalık sayı
7%E%e ile aynıOndalık sayı
8%gDuruma göre %f veya %e çıktısı, fazla 0'ları kaldırırOndalık sayı
9%bTamsayının ikili gösterimi çıktısıSayı
10%#bİkili tam gösterim çıktısıSayı
11%oTamsayının sekizlik gösterimi çıktısıTamsayı
12%#oTamsayının tam sekizlik gösterimi çıktısıTamsayı
13%xTamsayının küçük harf onaltılık gösterimi çıktısıSayı
14%#xTamsayının tam küçük harf onaltılık gösterimi çıktısıSayı
15%XTamsayının büyük harf onaltılık gösterimi çıktısıSayı
16%#XTamsayının tam büyük harf onaltılık gösterimi çıktısıSayı
17%vDeğeri orijinal şeklinde çıktı yapar, çoğunlukla veri yapılarının çıktısı için kullanılırHerhangi
18%+vStruct çıktısı verirken alan adlarını eklerHerhangi
19%#vTam Go söz dizimi formatında değer çıktısıHerhangi
20%tBoolean değeri çıktısıBoolean
21%TDeğerin Go dilindeki tür değerini çıktısıHerhangi
22%cUnicode koduna karşılık gelen karakter çıktısıint32
23%UKarakterin Unicode kodunu çıktısırune,byte
24%pPointer'ın işaret ettiği adresin çıktısıPointer

String'i biçimlendirmek veya biçimlendirilmiş string çıktısı yapmak için fmt.Sprintf veya fmt.Printf kullanın. Birkaç örneğe bakalım:

go
fmt.Printf("%%%s\n", "merhaba dünya")

fmt.Printf("%s\n", "merhaba dünya")
fmt.Printf("%q\n", "merhaba dünya")
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{})

Diğer tabanları kullanırken, % ile biçimlendirme belirleyicisi arasına boşluk ekleyerek ayırıcı efekti elde edebilirsiniz, örneğin:

go
func main() {
  str := "abcdefg"
  fmt.Printf("%x\n", str)
  fmt.Printf("% x\n", str)
}

Bu örneğin çıktısı:

61626364656667
61 62 63 64 65 66 67

Sayıları kullanırken, otomatik olarak sıfır da ekleyebilirsiniz. Örneğin:

go
fmt.Printf("%09d", 1)
// 000000001

İkili gösterim de aynı mantıkla çalışır:

go
fmt.Printf("%09b", 1<<3)
// 000001000

Hata Durumları

Biçimlendirme karakter sayısı < parametre listesi sayısı:

go
fmt.Printf("", "") //%!(EXTRA string=)

Biçimlendirme karakter sayısı > parametre listesi sayısı:

go
fmt.Printf("%s%s", "") //%!s(MISSING)

Tür eşleşmiyor:

go
fmt.Printf("%s", 1) //%!s(int=1)

Biçimlendirme belirleyicisi eksik:

go
fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)

Giriş

Aşağıda yaygın giriş yöntemleri tanıtılmaktadır.

read

Dosya okur gibi doğrudan giriş içeriğini okuyabilirsiniz, aşağıdaki gibi:

go
func main() {
  var buf [1024]byte
  n, _ := os.Stdin.Read(buf[:])
  os.Stdout.Write(buf[:n])
}

Bu kullanımı çok rahattır, genellikle önerilmez.

fmt

fmt paketi tarafından sağlanan birkaç fonksiyonu kullanabiliriz, kullanımı C ile benzerdir.

go
// os.Stdin'den okunan metni tarar, boşluğa göre ayırır, yeni satır da boşluk olarak kabul edilir
func Scan(a ...any) (n int, err error)

// Scan'a benzer, ancak yeni satırda taramayı durdurur
func Scanln(a ...any) (n int, err error)

// Biçimlendirilmiş string'e göre tarar
func Scanf(format string, a ...any) (n int, err error)

İki sayı okuma:

go
func main() {
  var a, b int
  fmt.Scanln(&a, &b)
  fmt.Printf("%d + %d = %d\n", a, b, a+b)
}

Sabit uzunlukta dizi okuma:

go
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

Çok fazla giriş okunması gerektiğinde, bufio.Reader kullanarak içerik okuma önerilir:

go
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'a benzer, ancak satır satır okur.

go
func main() {
  scanner := bufio.NewScanner(os.Stdin)
  for scanner.Scan() {
    line := scanner.Text()
    if line == "exit" {
      break
    }
    fmt.Println("scan", line)
  }
}

Sonuç:

first line
scan first line
second line
scan second line
third line
scan third line
exit

TIP

Giriş çıkış konusunda pratik yapmak isterseniz, Luogu sitesinde birkaç basit ACM modu algoritma sorusu çözerek alışabilirsiniz.

Golang by www.golangdev.cn edit