我正在尝试在 Go 中实现 PPM 解码器。PPM 是一种图像格式,由纯文本标题和一些二进制图像数据组成。标题看起来像这样(来自规范):
每个 PPM 图像包含以下内容:
用于识别文件类型的“幻数”。ppm 图像的幻数是两个字符“P6”。
空白(空格、制表符、CR、LF)。
宽度,格式为十进制 ASCII 字符。
空白。
高度,同样以 ASCII 十进制表示。
空白。
最大颜色值 (Maxval),同样以 ASCII 十进制表示。必须小于 65536 且大于零。
单个空白字符(通常是换行符)。
我尝试使用该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. 可以在他们返回的输入之后读取一个字符(符文),这意味着调用扫描例程的循环可能会跳过一些输入。这通常只有在输入值之间没有空格时才会出现问题。如果提供给Fscan实现 的阅读器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)
是否保证按照规范工作?
相关分类