web-dev-qa-db-fra.com

Comment puis-je convertir une chaîne en entier en golang

Je veux convertir une chaîne en entier en golang. Mais je ne connais pas le format de chaîne. Par exemple, "10" -> 10, "65.0" -> 65, "xx" -> 0, "11xx" -> 11, "xx11" -> 0

Je fais des recherches et trouve strconv.ParseInt(). Mais il ne peut pas gérer "65.0". Je dois donc vérifier le format de la chaîne.

Y a-t-il un meilleur moyen?

7
shenli3514

Je crois que la fonction que vous recherchez est 

strconv.ParseFloat()

voir exemple ici

Mais le type de retour de cette fonction est float64.

Si vous n'avez pas besoin d'une fraction du nombre passé en tant que fonction suivante, la fonction suivante fera le travail:

func StrToInt(str string) (int, error) {
    nonFractionalPart := strings.Split(str, ".")
    return strconv.Atoi(nonFractionalPart[0])
}
7
Mayank Patel
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)

Pour référence, cliquez ici

1
Deepak G

Je veux convertir une chaîne en entier en golang. 

Comme vous l'avez déjà mentionné, il existe une fonction strconv.ParseInt qui fait exactement cela!

Mais je ne connais pas le format de chaîne.

Cela semble effrayant (et stimulant), mais après avoir examiné vos exemples, je peux facilement en conclure que vous connaissez le format et que le problème peut être énoncé comme suit:

Comment puis-je analyser une partie initiale d'une chaîne comme un entier?

Comme strconv.ParseInt renvoie 0 en cas d'erreur de syntaxe, cela ne convient pas; du moins pas directement. Mais il peut analyser votre portion initiale si vous extraire il. Je suis sûr que vous l'avez déjà compris, mais c'est vraiment la solution la plus propre: extrayez votre contenu de la chaîne, analysez-le.

Vous pouvez extraire le premier entier de plusieurs façons, l'une d'entre elles consiste à utiliser 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 } _

Je crois que ce code est simple et démontre clairement les intentions. Vous utilisez également la variable ParseInt standard qui fonctionne et vous fournit toutes les vérifications d'erreur dont vous avez besoin.

Si, pour une raison quelconque, vous ne pouvez pas vous permettre d'extraire l'entier principal (vous avez besoin d'une analyse rapide de téraoctets de données et votre patron vous crie dessus, ils en ont besoin maintenant maintenant et mieux hier, alors courbez le temps et livrez-le: sifflement :) Je suggère de plonger dans le code source } et de modifier l’analyseur standard afin de ne pas signaler les erreurs de syntaxe, mais de renvoyer une partie analysée de la chaîne.

0
tomasz

Extraire un int depuis le début d'une chaîne est l'une des choses les plus courantes que je fais. En C, vous pouvez utiliser atoi () ou strtol (). C'est ridicule que Go n'ait pas de fonction de bibliothèque std pour le faire. En tout cas en voici un que je viens de retrousser

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

Vous aurez besoin d'une légère réparation si vous voulez gérer -ve entier.

0
Andrew W. Phillips

Vous pouvez écrire une FieldsFunc pour analyser et obtenir les valeurs numériques seules séparément.

Jouez ici

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

La sortie ici est

10 10
65.0 65
xx 0
11xx 11
xx11 11

Notez que votre dernière condition de xx11 le traite en tant que 11.

0
Sundar