如何在golang中将字符串转换为整数

时间:2015-07-18 04:08:39

标签: go casting type-conversion

我想在golang中将字符串转换为整数。但我不知道字符串的格式。例如,"10" - > 10"65.0" - > 65"xx" - > 0,“11xx” - > 11,“xx11” - > 0

我做了一些搜索并找到了strconv.ParseInt()。但它无法处理"65.0"。所以我必须检查字符串的格式。

有更好的方法吗?

8 个答案:

答案 0 :(得分:8)

我相信你正在寻找的功能是

strconv.ParseFloat()

参见示例here

但是这个函数的返回类型是float64。

如果您不需要传递数字的小数部分,因为字符串跟随函数可以完成工作:

func StrToInt(str string) (int, error) {
    nonFractionalPart := strings.Split(str, ".")
    return strconv.Atoi(nonFractionalPart[0])
}

答案 1 :(得分:2)

package main

import "strconv"
import "fmt"

// The built-in package "strconv" provides the number parsing.

//For `ParseInt`, the `10` means infer the base from
// the string. `64` requires that the result fit in 64
// bits.


value, err := strconv.ParseInt("123", 10, 64)
if err != nil {
    panic(err)
}
fmt.Println(value)

For reference, Click Here

答案 2 :(得分:2)

要添加@MayankPatel和@DeepakG的出色答案。字符串可以设置为各种数字类型。可以将各种数字类型设置为字符串。同样,“ true”可以设置为布尔值,true可以设置为字符串。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    //convert a string to another type
    f, _ := strconv.ParseFloat("70.99", 64)
    i, _ := strconv.Atoi(fmt.Sprintf("%.f", f))
    t, _ := strconv.ParseBool("true")
    c := []interface{}{[]byte("70.99"), f, i, rune(i), t}
    checkType(c) //[]uint8 [55 48 46 57 57], float64 70.99, int 71, int32 71, bool true

    //convert another type to a string
    c = []interface{}{fmt.Sprintf("%s", []byte("70.99")), fmt.Sprintf("%.f", f), strconv.Itoa(i), string(rune(i)), strconv.FormatBool(t)}
    checkType(c) //string 70.99, string 71, string 71, string G, string true
}

func checkType(s []interface{}) {
    for k, _ := range s {
        fmt.Printf("%T %v\n", s[k], s[k])
    }
}

字符串类型表示字符串值的集合。字符串值是一个字节序列(可能为空)。字节数称为字符串的长度,绝不能为负。字符串是不可变的。参见https://Golang.org/ref/spec#String_types

有三种将字符串解析为整数的方法,从最快的运行时间到最慢的运行:1. strconv.ParseInt(...)最快2. strconv.Atoi(...)仍然非常快3. fmt.Sscanf(。 ..)速度不是很快,但最灵活。参见https://stackoverflow.com/a/47317150/12817546

避免将字符串转换为[] byte:b:= [] byte。它分配一个新的内存空间并将整个内容复制到其中。参见https://stackoverflow.com/a/52943136/12817546。参见https://stackoverflow.com/a/41460993/12817546。行情已编辑。

答案 3 :(得分:2)

您可以使用这三个函数将字符串值转换为整数或浮点数。 注意:必须导入 strconv 内置包才能执行这些功能。

  1. func Atoi(s string) (int, error)

  2. func ParseInt(s string, base int, bitSize int) (i int64, err error)

  3. func ParseFloat(s string, bitSize int) (float64, error)

    package main
    import (
        "fmt"
        "strconv"
    )
    func main() {
        i, _ := strconv.Atoi("-42")
        fmt.Println(i)
    
        j,_ := strconv.ParseInt("-42",10,8)
        fmt.Println(j)
    
        k,_ := strconv.ParseFloat("-42.8",8)
        fmt.Println(k)
    

    }

答案 4 :(得分:0)

您可以编写FieldsFunc来解析并单独获取数字值。

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

这里的输出是

10 10
65.0 65
xx 0
11xx 11
xx11 11

请注意,xx11的最后一个条件将其处理为11。

答案 5 :(得分:0)

  

我想在golang中将字符串转换为整数。

正如您已经提到过的,有一个strconv.ParseInt函数正是这样做的!

  

但我不知道字符串的格式。

这听起来很可怕(也很具挑战性),但在看了你的例子之后我很容易得出结论你知道格式,问题可以这样陈述:

如何将字符串的初始部分解析为整数?

由于strconv.ParseInt在语法错误时返回0,因此不太适合;好吧,至少不是直接适合。但是可以解析你的初始部分,如果你提取它。我确定你已经弄明白了,但这确实是最干净的解决方案:从字符串中提取你的内容,解析它。

您可以通过几种方式提取前导整数,其中一种是使用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

我相信这段代码很简单,清楚地表明了意图。您还使用工作的标准ParseInt,并为您提供所需的所有错误检查。

如果出于任何原因你无法负担提取领先的整数(你需要快速解析数TB的数据而且你的老板正在尖叫你现在他们现在需要它现在和昨天更好,所以弯曲时间并交付它:hiss :)比我建议潜入source code并修改标准解析器所以它不报告语法错误,但返回字符串的解析部分。

答案 6 :(得分:0)

从字符串的开头提取int是我做的最常见的事情之一。在C中,您可以使用atoi()或strtol()。 Go没有std库函数来实现它是荒谬的。无论如何这里是我刚刚卷起来的那个:

// 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
}

如果你想处理-ve整数,你需要一点点修复。

答案 7 :(得分:-1)

我目前的解决方案是:

// 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                                                                                                           
 }