Go で PPM デコーダーを実装しようとしています。PPM は、平文のヘッダーとバイナリ イメージ データで構成されるイメージ形式です。ヘッダーは次のようになります (仕様から):
各 PPM イメージは、次のもので構成されます。
- ファイルの種類を識別するための「マジック ナンバー」。ppm イメージのマジック ナンバーは、「P6」の 2 文字です。
- 空白 (空白、TAB、CR、LF)。
- 10 進数の ASCII 文字としてフォーマットされた幅。
- 空白。
- ASCII 10 進数の高さ。
- 空白。
- 色の最大値 (Maxval) で、これも ASCII 10 進数です。65536 未満で 0 より大きい必要があります。
- 1 つの空白文字 (通常は改行)。
関数でこのヘッダーをデコードしようとしfmt.Fscanf
ます。次の呼び出し
fmt.Fscanf
は、ヘッダーを解析します (以下で説明する警告には対処していません)。
var magic string
var width, height, maxVal uint
fmt.Fscanf(input,"%2s %d %d %d",&magic,&width,&height,&maxVal)
状態のドキュメント:fmt
注:
Fscan
etc は、返された入力の 1 文字 (ルーン) を読み取ることができます。これは、スキャン ルーチンを呼び出すループが入力の一部をスキップする可能性があることを意味します。これは通常、入力値の間にスペースがない場合にのみ問題になります。リーダーがFscan
implements に提供されている場合ReadRune
、そのメソッドは文字の読み取りに使用されます。リーダーが も実装している場合UnreadRune
、そのメソッドは文字を保存するために使用され、連続した呼び出しでデータが失われることはありません。その機能を持たないリーダーにReadRune
とメソッドをアタッチするには、 を使用します。UnreadRune
bufio.NewReader
最後の空白の次の文字はすでに画像データの先頭であるため、fmt.Fscanf
読み取り後に消費した空白の数を確認する必要がありMaxVal
ます。私のコードは、呼び出し元によって提供されたリーダーで動作する必要があり、その一部はヘッダーの末尾を超えて読み取ってはならないため、バッファリングされたリーダーに何かをラップすることはオプションではありません。バッファリングされたリーダーは、実際に読みたい以上に入力から読み取る可能性があります。
一部のテストでは、最後にダミー文字を解析すると問題が解決することが示唆されています。
var magic string
var width, height, maxVal uint
var dummy byte
fmt.Fscanf(input,"%2s %d %d %d%c",&magic,&width,&height,&maxVal,&dummy)
それは仕様通りに動作することが保証されていますか?