Go/Standard library/fmt
表示
< Go | Standard library
fmtパッケージの概要
[編集]fmtパッケージは、Go言語において最も頻繁に使用されるパッケージの一つです。このパッケージは、フォーマットされた入出力機能を提供し、テキストの出力、入力、文字列の整形などを行うことができます。
- fmtパッケージの主な機能:
- 標準出力への出力
- 動詞を使用した文字列整形
- 標準入力からの読み取り
- 文字列の作成と変換
基本的な出力関数
[編集]Print系関数
[編集]fmtパッケージには、出力を行うための3つの基本的な関数があります。
package main import "fmt" func main() { // Print - 引数を出力(改行なし) fmt.Print("Hello") fmt.Print("World") // 出力: HelloWorld // Println - 引数を出力して改行 fmt.Println("Hello") fmt.Println("World") // 出力: // Hello // World // Printf - 動詞を使用 name := "太郎" age := 25 fmt.Printf("名前: %s, 年齢: %d\n", name, age) // 出力: 名前: 太郎, 年齢: 25 }
各関数の特徴
[編集]- Print(): 引数をそのまま出力し、改行は行いません
- Println(): 引数を出力した後に改行を追加します
- Printf(): 動詞を使用して、より柔軟な出力が可能です
動詞
[編集]Printf関数で使用する動詞(verbs)は、出力の形式を制御する重要な機能です。
基本的な動詞
[編集]package main import "fmt" func main() { // 一般的な値の出力 fmt.Printf("%v\n", 42) // 42 fmt.Printf("%+v\n", 42) // +42 fmt.Printf("%#v\n", 42) // 42 fmt.Printf("%T\n", 42) // int // 文字列 fmt.Printf("%s\n", "Hello") // Hello fmt.Printf("%q\n", "Hello") // "Hello" fmt.Printf("%x\n", "Hello") // 48656c6c6f // 整数 fmt.Printf("%d\n", 42) // 42 fmt.Printf("%b\n", 42) // 101010 fmt.Printf("%o\n", 42) // 52 fmt.Printf("%x\n", 42) // 2a fmt.Printf("%X\n", 42) // 2A // 浮動小数点数 fmt.Printf("%f\n", 3.14159) // 3.141590 fmt.Printf("%.2f\n", 3.14159) // 3.14 fmt.Printf("%e\n", 3.14159) // 3.141590e+00 fmt.Printf("%g\n", 3.14159) // 3.14159 // ブール値 fmt.Printf("%t\n", true) // true // ポインタ x := 42 fmt.Printf("%p\n", &x) // 0xc0000140a8(メモリアドレス) }
動詞の詳細 指定子 説明 例 %vデフォルトフォーマット 42,"hello"%+v構造体のフィールド名付き {Name:太郎 Age:25}%#vGo構文表現 []string{"a", "b"}%T型情報 int,string%s文字列 hello%qクォート付き文字列 "hello"%d10進数 42%b2進数 101010%o8進数 52%x16進数(小文字) 2a%X16進数(大文字) 2A%f浮動小数点数 3.141590%e指数表記(小文字) 3.141590e+00%E指数表記(大文字) 3.141590E+00%g短い方の%fまたは%e 3.14159%G短い方の%fまたは%E 3.14159%tブール値 true%pポインタ 0xc0000140a8
幅と精度の指定
[編集]動詞には、出力の幅や精度を指定することができます。
package main import "fmt" func main() { // 幅の指定 fmt.Printf("|%5d|\n", 42) // | 42| fmt.Printf("|%-5d|\n", 42) // |42 fmt.Printf("|%05d|\n", 42) // |00042| // 浮動小数点の精度指定 fmt.Printf("%.2f\n", 3.14159) // 3.14 fmt.Printf("%8.2f\n", 3.14159) // 3.14(幅8、精度2) // 文字列の幅指定 fmt.Printf("|%10s|\n", "Hello") // | Hello| fmt.Printf("|%-10s|\n", "Hello") // |Hello fmt.Printf("|%.3s|\n", "Hello") // |Hel| }
Sprint系関数
[編集]Sprint系関数は、出力する代わりに文字列を返します。
package main import "fmt" func main() { // Sprint - 文字列として返す str1 := fmt.Sprint("Hello", "World") fmt.Println(str1) // HelloWorld // Sprintln - 改行付きで文字列として返す str2 := fmt.Sprintln("Hello", "World") fmt.Println(str2) // Hello World\n // Sprintf - 動詞を使用 name := "太郎" age := 25 str3 := fmt.Sprintf("名前: %s, 年齢: %d", name, age) fmt.Println(str3) // 名前: 太郎, 年齢: 25 }
Fprint系関数
[編集]Fprint系関数は、指定したio.Writerに出力を行います。
package main import ( "fmt" "os" "strings" ) func main() { // 標準出力に出力 fmt.Fprint(os.Stdout, "Hello, World!\n") // 標準エラー出力に出力 fmt.Fprint(os.Stderr, "Error message\n") // strings.Builderに出力 var builder strings.Builder fmt.Fprint(&builder, "Hello, ") fmt.Fprint(&builder, "World!") fmt.Println(builder.String()) // Hello, World! }
入力関数
[編集]fmtパッケージには、標準入力から読み取りを行う関数も含まれています。
package main import "fmt" func main() { var name string var age int // Scan - 空白区切りで読み取り fmt.Print("名前と年齢を入力してください: ") fmt.Scan(&name, &age) fmt.Printf("名前: %s, 年齢: %d\n", name, age) // Scanln - 改行まで読み取り var input string fmt.Print("一行入力してください: ") fmt.Scanln(&input) fmt.Printf("入力: %s\n", input) // Scanf - フォーマット指定で読み取り var x, y int fmt.Print("2つの数値を 'x,y' の形式で入力してください: ") fmt.Scanf("%d,%d", &x, &y) fmt.Printf("x=%d, y=%d\n", x, y) }
構造体の出力
[編集]構造体を出力する際の動詞の使い分けを理解することは重要です。
package main import "fmt" type Person struct { Name string Age int } func main() { p := Person{Name: "太郎", Age: 25} fmt.Printf("%v\n", p) // {太郎 25} fmt.Printf("%+v\n", p) // {Name:太郎 Age:25} fmt.Printf("%#v\n", p) // main.Person{Name:"太郎", Age:25} fmt.Printf("%T\n", p) // main.Person }
エラーハンドリング
[編集]入力関数を使用する際は、エラーハンドリングを適切に行うことが重要です。
package main import ( "fmt" "log" ) func main() { var number int fmt.Print("数値を入力してください: ") if n, err := fmt.Scan(&number); err != nil { log.Printf("入力エラー: %v", err) return } else { fmt.Printf("読み取った項目数: %d\n", n) fmt.Printf("入力された数値: %d\n", number) } }
カスタムフォーマット
[編集]独自の型にカスタムフォーマットを実装することも可能です。
package main import "fmt" type Point struct { X, Y int } // String メソッドを実装すると %s や %v で使用される func (p Point) String() string { return fmt.Sprintf("(%d, %d)", p.X, p.Y) } func main() { p := Point{X: 3, Y: 4} fmt.Printf("%s\n", p) // (3, 4) fmt.Printf("%v\n", p) // (3, 4) }
パフォーマンス考慮事項
[編集]fmtパッケージの使用においては、パフォーマンスを考慮する場面があります。
package main import ( "fmt" "strings" ) func main() { // 効率的でない例 result := "" for i := range 1000 { result += fmt.Sprintf("Item %d\n", i) } // より効率的な例 var builder strings.Builder for i := range 1000 { fmt.Fprintf(&builder, "Item %d\n", i) } result = builder.String() }
実践的な使用例
[編集]ログ出力
[編集]package main import ( "fmt" "os" "time" ) func logMessage(level, message string) { timestamp := time.Now().Format("2006-01-02 15:04:05") fmt.Fprintf(os.Stderr, "[%s] %s: %s\n", timestamp, level, message) } func main() { logMessage("INFO", "アプリケーション開始") logMessage("ERROR", "ファイルが見つかりません") }
テーブル形式の出力
[編集]package main import "fmt" type Product struct { Name string Price int Stock int } func main() { products := []Product{ {"リンゴ", 100, 50}, {"バナナ", 80, 30}, {"オレンジ", 120, 20}, } fmt.Printf("%-10s %5s %5s\n", "商品名", "価格", "在庫") fmt.Println("------------------------") for _, p := range products { fmt.Printf("%-10s %5d %5d\n", p.Name, p.Price, p.Stock) } }
まとめ
[編集]fmtパッケージは、Go言語における基本的かつ重要なパッケージです。適切に使用することで、読みやすく保守性の高いコードを書くことができます。
- 重要なポイント:
- Print系関数の使い分け
- 動詞の理解
- エラーハンドリングの重要性
- パフォーマンスを考慮した使用方法
次の章では、Go言語のエラーハンドリングについて詳しく学習します。
練習問題
[編集]- 以下の出力を生成するプログラムを書いてください:
名前: 田中太郎 年齢: 30歳 身長: 175.5cm
- 標準入力から2つの整数を読み取り、その和、差、積、商を表示するプログラムを作成してください。
- 構造体を定義し、%v、%+v、%#vの違いを確認するプログラムを作成してください。
- 1から100までの数値を、5列のテーブル形式で出力するプログラムを作成してください。