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?

+3


source to share


5 answers


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])
}

      

+5


source


You can write FieldsFunc

to parse and get the number values ​​separately.

Play it here

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.

0


source


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.

0


source


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.

0


source


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                                                                                                           
 }    

      

-1


source







All Articles