0

Go で PPM デコーダーを実装しようとしています。PPM は、平文のヘッダーとバイナリ イメージ データで構成されるイメージ形式です。ヘッダーは次のようになります (仕様から):

各 PPM イメージは、次のもので構成されます。

  1. ファイルの種類を識別するための「マジック ナンバー」。ppm イメージのマジック ナンバーは、「P6」の 2 文字です。
  2. 空白 (空白、TAB、CR、LF)。
  3. 10 進数の ASCII 文字としてフォーマットされた幅。
  4. 空白。
  5. ASCII 10 進数の高さ。
  6. 空白。
  7. 色の最大値 (Maxval) で、これも ASCII 10 進数です。65536 未満で 0 より大きい必要があります。
  8. 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

注: Fscanetc は、返された入力の 1 文字 (ルーン) を読み取ることができます。これは、スキャン ルーチンを呼び出すループが入力の一部をスキップする可能性があることを意味します。これは通常、入力値の間にスペースがない場合にのみ問題になります。リーダーがFscanimplements に提供されている場合ReadRune、そのメソッドは文字の読み取りに使用されます。リーダーが も実装している場合UnreadRune、そのメソッドは文字を保存するために使用され、連続した呼び出しでデータが失われることはありません。その機能を持たないリーダーに ReadRune とメソッドをアタッチするには、 を使用します。UnreadRunebufio.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)

それは仕様通りに動作することが保証されていますか?

4

1 に答える 1