入出力

Go言語の標準入力の基本を解説

Go言語で標準入力を取り扱う基本的な方法について説明します。

ユーザーの入力をプログラムで受け取り、応じた処理を実現する手法や流れをシンプルな例を交えて解説します。

Go言語の標準入力基本操作

このセクションでは、Go言語で標準入力を扱う基本的な方法について説明します。

各方法の特徴や使い分けを具体的なサンプルコードと共にご紹介します。

fmtパッケージを使った入力取得

fmtパッケージは、簡単な入力受付に適しており、ユーザからの入力を変数に直接格納することができます。

fmt.Scan, fmt.Scanln, fmt.Scanfの使い分け

fmt.Scanfmt.Scanlnfmt.Scanfはそれぞれ用途が異なります。

fmt.Scanは空白で区切られたトークンを読み取り、

fmt.Scanlnは改行を区切りとして読み取ります。

fmt.Scanfはフォーマットに沿った入力を取得するため、書式指定子を使ってデータを変換する場合に有用です。

以下にサンプルコードを示します。

package main
import (
	"fmt"
)
func main() {
	// fmt.Scanによる入力取得例
	var inputString string
	fmt.Print("文字列を入力してください: ")
	// 空白で区切られた最初のトークンを取得
	fmt.Scan(&inputString)
	fmt.Printf("受け取った文字列: %s\n", inputString)
	// fmt.Scanlnによる入力取得例
	var inputInt int
	fmt.Print("整数を入力してください: ")
	// 改行までの入力を取得
	fmt.Scanln(&inputInt)
	fmt.Printf("受け取った整数: %d\n", inputInt)
	// fmt.Scanfによる入力取得例
	var inputFormatted string
	fmt.Print("フォーマットに沿った入力をしてください: ")
	// 書式指定子 "%s" により入力を受け取る
	fmt.Scanf("%s", &inputFormatted)
	fmt.Printf("受け取った入力: %s\n", inputFormatted)
}
文字列を入力してください: Hello World
受け取った文字列: Hello
整数を入力してください: 123
受け取った整数: 123
フォーマットに沿った入力をしてください: GoLang
受け取った入力: GoLang

bufioパッケージによる入力処理

bufioパッケージは、バッファを利用して入力を処理するため、大量の入力や複数行の入力に適しています。

以下に、bufio.Readerbufio.Scannerを使った方法をご紹介します。

bufio.Readerによる入力取得方法

bufio.NewReaderを使えば、改行文字が現れるまでの文字列全体をまとめて取得できます。

入力された文字列から余分な改行を削除する場合は、strings.TrimSpaceなどで処理する必要があります。

package main
import (
	"bufio"
	"fmt"
	"os"
	"strings"
)
func main() {
	// bufio.Readerの生成
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("入力を記述してください: ")
	// 改行文字が現れるまで入力を受け取る
	line, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("入力エラーです:", err)
		return
	}
	// 余分な改行文字等を削除
	line = strings.TrimSpace(line)
	fmt.Println("受け取った入力:", line)
}
入力を記述してください: サンプル入力
受け取った入力: サンプル入力

bufio.Scannerでの行単位入力取得

bufio.Scannerは、標準入力から1行ずつ読み取るのに便利です。

EOFや特定の終了条件がある場合、ループ処理で各行を処理できます。

package main
import (
	"bufio"
	"fmt"
	"os"
)
func main() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Println("複数行の入力を記述してください。(終了するには \"exit\" と入力):")
	// スキャナで1行ずつ読み取る
	for scanner.Scan() {
		line := scanner.Text()
		if line == "exit" {
			break
		}
		fmt.Println("入力された行:", line)
	}
	// 入力処理中のエラーをチェック
	if err := scanner.Err(); err != nil {
		fmt.Println("入力中にエラーが発生しました:", err)
	}
}
複数行の入力を記述してください。(終了するには "exit" と入力):
最初の行
入力された行: 最初の行
次の行
入力された行: 次の行
exit

osパッケージを使った標準入力の操作

osパッケージを直接使う場合は、os.Stdinからバイト列を読み取る方法が採られます。

バイトレベルでの読み取りが必要なときなどに有用です。

os.Stdinの利用方法

以下は、os.Stdin.Readを利用して、標準入力から指定バイト数のデータを受け取るサンプルプログラムです。

package main
import (
	"fmt"
	"os"
)
func main() {
	// バッファサイズ1024バイトの配列を作成
	buffer := make([]byte, 1024)
	fmt.Print("入力してください: ")
	// os.Stdinからバイト列を読み取る
	n, err := os.Stdin.Read(buffer)
	if err != nil {
		fmt.Println("エラー:", err)
		return
	}
	// バイト数nだけのデータを文字列に変換して表示
	fmt.Printf("受け取った入力: %s", string(buffer[:n]))
}
入力してください: これはテスト入力です。
受け取った入力: これはテスト入力です。

入力検証とエラーチェック

ここでは、入力内容の検証方法と、エラーが発生した場合の対処法について説明します。

ユーザからの入力は予期しない値が入る可能性がありますので、エラーチェックは必須です。

入力エラーの検出方法

入力エラーは、関数の戻り値でエラーが報告されるケースがほとんどです。

例えば、fmt.Sscanfを用いて数値に変換するときに、変換に失敗すればエラーが返されます。

以下のサンプルでは、整数の入力を検証する方法を示しています。

package main
import (
	"bufio"
	"fmt"
	"os"
)
func main() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("数字を入力してください: ")
	scanner.Scan()
	input := scanner.Text()
	var value int
	// 入力文字列から%dフォーマットによって整数を取得
	_, err := fmt.Sscanf(input, "%d", &value)
	if err != nil {
		fmt.Println("入力エラーです。整数ではありません。")
		return
	}
	fmt.Printf("受け取った整数: %d\n", value)
}
数字を入力してください: abc
入力エラーです。整数ではありません。

エラー処理の実装ポイント

エラー処理では、必ずエラーが発生した場合に適切な対処を行うようにします。

エラー内容をユーザに知らせるとともに、プログラムが無用に実行を続けないようにすることが重要です。

以下は、入力エラーや空入力を検知して処理を中断する例です。

package main
import (
	"bufio"
	"fmt"
	"os"
	"strings"
)
func main() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("メッセージを入力してください: ")
	line, err := reader.ReadString('\n')
	if err != nil {
		// エラー発生時はその旨を表示して終了
		fmt.Println("入力の読み込みエラーが発生しました:", err)
		return
	}
	line = strings.TrimSpace(line)
	if line == "" {
		// 空の入力の場合の対応
		fmt.Println("入力が空です。")
		return
	}
	fmt.Println("受け取ったメッセージ:", line)
}
メッセージを入力してください:
入力が空です。

実践的な入力処理の活用例

ここからは、実際に入力処理を組み合わせたシンプルなプログラム例を紹介し、その基本構成と実行結果を解析します。

シンプルな入力受付プログラムの例

プログラムの基本構成

以下のサンプルコードは、ユーザから名前と年齢を順に入力して受け取り、結果を出力するプログラムです。

bufio.NewReaderを使って文字列入力を取得し、fmt.Scanを使って数値入力を取得する方法を組み合わせています。

package main
import (
	"bufio"
	"fmt"
	"os"
	"strings"
)
func main() {
	// ユーザに名前の入力を求める
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("お名前を入力してください: ")
	name, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("名前の入力エラーです:", err)
		return
	}
	name = strings.TrimSpace(name)
	// ユーザに年齢の入力を求める
	fmt.Print("年齢を入力してください: ")
	var age int
	_, err = fmt.Scan(&age)
	if err != nil {
		fmt.Println("年齢の入力エラーです。整数を入力してください。")
		return
	}
	// 入力結果の表示
	fmt.Printf("あなたのお名前は %s で、年齢は %d 歳ですね。\n", name, age)
}
お名前を入力してください: 山田太郎
年齢を入力してください: 28
あなたのお名前は 山田太郎 で、年齢は 28 歳ですね。

実行結果の解析

このプログラムでは、まずbufio.Readerを用いて名前を取得し、続いてfmt.Scanで年齢を入力として受け取ります。

・名前入力時には、ユーザが入力した文字列の末尾に含まれる改行コードをstrings.TrimSpaceで削除しています。

・年齢入力時には、数値変換が失敗した場合にエラーを検知し、適切なエラーメッセージを表示するようになっています。

このように、各入力方法の特性を理解し、適切なエラーチェックを組み合わせることで、堅牢な入力処理プログラムを実装することが可能です。

まとめ

この記事では、Go言語で標準入力を扱う基本操作、入力検証およびエラーチェックの実装方法を、各種パッケージとサンプルコードを通して具体的に解説しました。

全体として、各手法の特徴や注意点が整理され、効率的な入力処理の実装に役立つ内容となっています。

ぜひサンプルコードを実際に実行して、理解を深めた上で自分のプロジェクトに取り入れてみてください。

関連記事

Back to top button