How to convert string to integer in golang
I want to convert string to integer in golang. But I don't know the format of the string. For example, "10"
β 10
, "65.0"
β 65
, "xx"
β 0
, "11xx" β 11, "xx11" β 0
I searched a bit and found strconv.ParseInt()
. But he can't handle it "65.0"
. So I have to check the format of the string.
Is there a better way?
source to share
I believe the function you are looking for is
strconv.ParseFloat()
see example here
But the return type of this function is float64.
If you don't need the fractional part of the number passed as the following function, executed by the following line:
func StrToInt(str string) (int, error) {
nonFractionalPart := strings.Split(str, ".")
return strconv.Atoi(nonFractionalPart[0])
}
source to share
You can write FieldsFunc
to parse and get the number values ββseparately.
package main
import (
"fmt"
"strconv"
"strings"
"unicode"
)
func stripNonIntFloat(s string) string {
f := func(c rune) bool {
return !unicode.IsNumber(c) && (c != 46)
}
output := strings.FieldsFunc(s, f)
if len(output) > 0 {
return output[0]
} else {
return ""
}
}
func main() {
strList := []string{"10", "65.0", "xx", "11xx", "xx11"}
for i := 0; i < len(strList); i++ {
s := stripNonIntFloat(strList[i])
v, err := strconv.ParseFloat(s, 10)
if err != nil {
fmt.Println(strList[i], 0)
} else {
fmt.Println(strList[i], v)
}
}
}
Result here
10 10
65.0 65
xx 0
11xx 11
xx11 11
Note that your last xx11 condition treats it as 11.
source to share
I want to convert string to integer in golang.
As you mentioned, there is a function strconv.ParseInt
that does exactly that!
But I don't know the format of the string.
It sounds scary (and difficult), but looking at your examples, I can easily conclude that you know the format and the problem can be formulated like this:
How can I parse the initial part of a string as an integer?
Since it strconv.ParseInt
returns 0 on syntax error, this is inappropriate; good, at least not very good fit. But it can analyze your initial part if you extract it. I'm sure you figured it out by now, but this is really the cleanest solution: extract the content from the string, parse it.
You can extract the leading integer in several ways, one of which is regexp
:
package main
import (
"fmt"
"regexp"
"strconv"
)
// Extract what you need
var leadingInt = regexp.MustCompile(`^[-+]?\d+`)
func ParseLeadingInt(s string) (int64, error) {
s = leadingInt.FindString(s)
if s == "" { // add this if you don't want error on "xx" etc
return 0, nil
}
return strconv.ParseInt(s, 10, 64)
}
func main() {
for _, s := range []string{"10", "65.0", "xx", "11xx", "xx11"} {
i, err := ParseLeadingInt(s)
fmt.Printf("%s\t%d\t%v\n", s, i, err)
}
}
http://play.golang.org/p/d7sS5_WpLj
I think this code is simple and clearly demonstrates the intent. You also use the standard one ParseInt
, which works and gives you all the error checking you need.
If for some reason you can't afford to extract the leading integer (you need him to get rich quick on terabytes of data and your boss yells at you, he needs now now and better yesterday, so bend the time and deliver it : hiss :) than I suggest diving into the source code and tweaking the standard parser so it doesn't report syntax errors, but returns the parsed part of the string.
source to share
Extracting int from the beginning of a string is one of the more common things I do. In C, you can use atoi () or strtol (). It's funny that Go doesn't have a std library function to do this. Anyway, here I just collapsed:
// strToInt gets the integer from the start of the string.
// It returns the value and the offset of the first non-digit.
func StrToInt(s string) (v int, offset int) {
offset = strings.IndexFunc(s, func(r rune) bool { return r < '0' || r > '9' })
if offset == -1 { offset = len(s) }
if offset == 0 { return } // Avoid Atoi on empty string
v, _ = strconv.Atoi(s[:offset])
return
}
You need a little fix if you want to handle -ve integers.
source to share
My current solution:
// Convert string to integer in best effort.
// TODO: handle overflow and add unittest
func StrToInt(str string) (int64, error) {
if len(str) == 0 {
return 0, nil
}
negative := false
i := 0
if str[i] == '-' {
negative = true
i++
} else if str[i] == '+' {
i++
}
r := int64(0)
for ; i < len(str); i++ {
if unicode.IsDigit(rune(str[i])) {
r = r*10 + int64(str[i]-'0')
} else {
break
}
}
if negative {
r = -r
}
// TODO: if i < len(str), we should return error
return r, nil
}
source to share