strconv.ParseInt在数字以0开头时会失败。

huangapple go评论130阅读模式
英文:

strconv.ParseInt fails if number starts with 0

问题

我目前遇到了在Go语言中解析以0开头的一些数字的问题。

fmt.Println(strconv.ParseInt("0491031", 0, 64))

> 0 strconv.ParseInt: 解析"0491031"时出现无效语法

GoPlayground链接:https://go.dev/play/p/TAv7IEoyI8I

我认为这是由于一些基数转换错误导致的,但我不知道如何修复它。
我在解析一个超过5GB的CSV文件时遇到了这个错误,如果你需要更多细节,请告诉我。

[这个错误是由GoCSV库引起的,该库不允许为要解析的数字指定基数。]

英文:

I'm currently having issues parsing some numbers starting with 0 in Go.

fmt.Println(strconv.ParseInt("0491031", 0, 64))

> 0 strconv.ParseInt: parsing "0491031": invalid syntax

GoPlayground: https://go.dev/play/p/TAv7IEoyI8I

I think this is due to some base conversion error, but I don't have ideas about how to fix it.
I'm getting this error parsing a 5GB+ csv file with gocsv, if you need more details.

[This error was caused by the GoCSV library that doesn't allow to specify a base for the numbers you're going to parse.]

答案1

得分: 5

strconv.ParseInt()引用:

> 如果基数参数为0,则基数由字符串的前缀隐含确定(如果存在符号):对于“0b”,基数为2;对于“0”或“0o”,基数为8;对于“0x”,基数为16;否则,基数为10。此外,仅对于基数为0的参数,根据Go语法中整数字面量的定义,允许使用下划线字符。

你将base参数设置为0,因此将从字符串值中推断出要解析的基数。由于字符串以'0'开头,后面跟着一个非'0'的字符,因此你的数字被解释为八进制(8进制)数字,而数字9在八进制中是无效的。

请注意,以下代码可以正常工作:

fmt.Println(strconv.ParseInt("0431031", 0, 64))

输出结果为(在Go Playground上尝试):

143897 <nil>

(八进制431031等于十进制143897。)

如果你的输入是十进制,请将base设置为10

fmt.Println(strconv.ParseInt("0491031", 10, 64))

然后输出结果为(在Go Playground上尝试):

491031 <nil>
英文:

Quoting from strconv.ParseInt()

> If the base argument is 0, the true base is implied by the string's prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise. Also, for argument base 0 only, underscore characters are permitted as defined by the Go syntax for integer literals.

You are passing 0 for base, so the base to parse in will be inferred from the string value, and since it starts with a &#39;0&#39; followed by a non &#39;0&#39;, your number is interpreted as an octal (8) number, and the digit 9 is invalid there.

Note that this would work:

fmt.Println(strconv.ParseInt(&quot;0431031&quot;, 0, 64))

And output (try it on the Go Playground):

143897 &lt;nil&gt;

(Octal 431031 equals 143897 decimal.)

If your input is in base 10, pass 10 for base:

fmt.Println(strconv.ParseInt(&quot;0491031&quot;, 10, 64))

Then output will be (try it on the Go Playground):

491031 &lt;nil&gt;

huangapple
  • 本文由 发表于 2021年12月14日 03:07:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/70339720.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定