使用fmt.Sscanf报unexpected EOF?

yecz · · 1389 次点击
// Sscanf scans the argument string, storing successive space-separated // values into successive arguments as determined by the format. It // returns the number of items successfully parsed. // Newlines in the input must match newlines in the format.
#1
更多评论
// Sscanf scans the argument string, storing successive space-separated // values into successive arguments as determined by the format. It // returns the number of items successfully parsed. // Newlines in the input must match newlines in the format. func Sscanf(str string, format string, a ...any) (n int, err error) { return Fscanf((*stringReader)(&str), format, a...) }
#2
jan-bar
想要拥有,必定付出。
当你执行下面代码会发现,第一个`a`把剩余所有字符串都获取了 ```go package main import ( &#34;fmt&#34; &#34;log&#34; ) func main() { var ( str = &#34;a=aaa,b=bbb,c=ccc&#34; format = &#34;a=%s,b=%s,c=%s&#34; a string b string c string ) if _, err := fmt.Sscanf(str, format, &amp;a, &amp;b, &amp;c); err != nil { log.Println(err) } log.Println(&#34;a:&#34;, a) log.Println(&#34;b:&#34;, b) log.Println(&#34;c:&#34;, c) } 结果如下 2022/09/21 17:50:04 unexpected EOF 2022/09/21 17:50:04 a: aaa,b=bbb,c=ccc 2022/09/21 17:50:04 b: 2022/09/21 17:50:04 c: ``` 你可以增加空格,因为`scanf`默认都是已空格或者制表符之类的作为分隔,下面这种方式需要两种字符串都已空格分开 ```go package main import ( &#34;fmt&#34; &#34;log&#34; ) func main() { var ( str = &#34;a=aaa ,b=bbb ,c=ccc&#34; format = &#34;a=%s ,b=%s ,c=%s&#34; a string b string c string ) if _, err := fmt.Sscanf(str, format, &amp;a, &amp;b, &amp;c); err != nil { log.Println(err) } log.Println(&#34;a:&#34;, a) log.Println(&#34;b:&#34;, b) log.Println(&#34;c:&#34;, c) } 结果如下 2022/09/21 17:54:58 a: aaa 2022/09/21 17:54:58 b: bbb 2022/09/21 17:54:58 c: ccc ``` 下面方法我将扫描分隔符改为逗号,完全满足你的需求 ```go package main import ( &#34;fmt&#34; &#34;log&#34; ) func main() { var ( str = &#34;a=aaa,b=bbb,c=ccc&#34; format = &#34;a=%s,b=%s,c=%s&#34; a, b, c string ) if _, err := fmt.Sscanf(str, format, (*mm)(&amp;a), (*mm)(&amp;b), (*mm)(&amp;c)); err != nil { log.Println(err) } log.Println(&#34;a:&#34;, a) log.Println(&#34;b:&#34;, b) log.Println(&#34;c:&#34;, c) } type mm string func (m *mm) Scan(state fmt.ScanState, verb rune) error { tok, err := state.Token(true, func(r rune) bool { return r != &#39;,&#39; // 默认string以空格分隔,我这里改为用逗号分隔 }) if err != nil { return err } *m = mm(tok) return nil } 结果如下 2022/09/21 17:55:28 a: aaa 2022/09/21 17:55:28 b: bbb 2022/09/21 17:55:28 c: ccc ``` 我又修改了下,感觉把类型改为自定义使用起来比较麻烦。这下更完美了。 <a href="/user/Mericusta" title="@Mericusta">@Mericusta</a> <a href="/user/yecz" title="@yecz">@yecz</a>
#3